MPEGProgramStreamParser Class Reference

Inheritance diagram for MPEGProgramStreamParser:

Inheritance graph
[legend]
Collaboration diagram for MPEGProgramStreamParser:

Collaboration graph
[legend]

Public Member Functions

 MPEGProgramStreamParser (MPEG1or2Demux *usingSource, FramedSource *inputSource)
virtual ~MPEGProgramStreamParser ()
unsigned char parse ()
virtual void flushInput ()

Protected Types

typedef void( clientContinueFunc )(void *clientData, unsigned char *ptr, unsigned size, struct timeval presentationTime)

Protected Member Functions

void saveParserState ()
virtual void restoreSavedParserState ()
u_int32_t get4Bytes ()
u_int32_t test4Bytes ()
u_int16_t get2Bytes ()
u_int8_t get1Byte ()
void getBytes (u_int8_t *to, unsigned numBytes)
void skipBytes (unsigned numBytes)
void skipBits (unsigned numBits)
unsigned getBits (unsigned numBits)
unsigned curOffset () const
unsigned & totNumValidBytes ()

Private Member Functions

void setParseState (MPEGParseState parseState)
void parsePackHeader ()
void parseSystemHeader ()
unsigned char parsePESPacket ()
Boolean isSpecialStreamId (unsigned char stream_id) const

Private Attributes

MPEG1or2DemuxfUsingSource
MPEGParseState fCurrentParseState

Detailed Description

Definition at line 35 of file MPEG1or2Demux.cpp.


Member Typedef Documentation

typedef void( StreamParser::clientContinueFunc)(void *clientData, unsigned char *ptr, unsigned size, struct timeval presentationTime) [protected, inherited]

Definition at line 33 of file StreamParser.hh.


Constructor & Destructor Documentation

MPEGProgramStreamParser::MPEGProgramStreamParser ( MPEG1or2Demux usingSource,
FramedSource inputSource 
)

Definition at line 325 of file MPEG1or2Demux.cpp.

00327   : StreamParser(inputSource, MPEG1or2Demux::handleClosure, usingSource,
00328                  &MPEG1or2Demux::continueReadProcessing, usingSource),
00329   fUsingSource(usingSource), fCurrentParseState(PARSING_PACK_HEADER) {
00330 }

MPEGProgramStreamParser::~MPEGProgramStreamParser (  )  [virtual]

Definition at line 332 of file MPEG1or2Demux.cpp.

00332                                                   {
00333 }


Member Function Documentation

unsigned char MPEGProgramStreamParser::parse (  ) 

Definition at line 340 of file MPEG1or2Demux.cpp.

References fCurrentParseState, parsePackHeader(), parsePESPacket(), parseSystemHeader(), PARSING_PACK_HEADER, PARSING_PES_PACKET, and PARSING_SYSTEM_HEADER.

Referenced by MPEG1or2Demux::continueReadProcessing().

00340                                              {
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 /*e*/) {
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;  // the parsing got interrupted
00368   }
00369 }

void MPEGProgramStreamParser::setParseState ( MPEGParseState  parseState  )  [private]

Definition at line 335 of file MPEG1or2Demux.cpp.

References fCurrentParseState, and StreamParser::saveParserState().

Referenced by parsePackHeader(), parsePESPacket(), and parseSystemHeader().

00335                                                                      {
00336   fCurrentParseState = parseState;
00337   saveParserState();
00338 }

void MPEGProgramStreamParser::parsePackHeader (  )  [private]

Definition at line 380 of file MPEG1or2Demux.cpp.

References Medium::envir(), MPEG1or2Demux::SCR::extension, MPEG1or2Demux::fLastSeenSCR, MPEG1or2Demux::fMPEGversion, fUsingSource, StreamParser::get1Byte(), StreamParser::get4Bytes(), StreamParser::getBits(), MPEG1or2Demux::SCR::highBit, isPacketStartCode(), MPEG1or2Demux::SCR::isValid, PACK_START_CODE, PARSING_PACK_HEADER, PARSING_PES_PACKET, PARSING_SYSTEM_HEADER, MPEG1or2Demux::SCR::remainingBits, setParseState(), StreamParser::skipBits(), StreamParser::skipBytes(), SYSTEM_HEADER_START_CODE, StreamParser::test4Bytes(), and True.

Referenced by parse().

00380                                               {
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     // We're supposed to have a pack header here, but check also for
00389     // a system header or a PES packet, just in case:
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); // ensures we progress over bad data
00408     if ((first4Bytes&0xFF) > 1) { // a system code definitely doesn't start here
00409       skipBytes(4);
00410     } else {
00411       skipBytes(1);
00412     }
00413   }
00414 
00415   // The size of the pack header differs depending on whether it's
00416   // MPEG-1 or MPEG-2.  The next byte tells us this:
00417   unsigned char nextByte = get1Byte();
00418   MPEG1or2Demux::SCR& scr = fUsingSource->fLastSeenSCR; // alias
00419   if ((nextByte&0xF0) == 0x20) { // MPEG-1
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) { // MPEG-2
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 { // unknown
00459     fUsingSource->envir() << "StreamParser::parsePack() saw strange byte "
00460                           << (void*)nextByte
00461                           << " following pack_start_code\n";
00462   }
00463 
00464   // Check for a System Header next:
00465   setParseState(PARSING_SYSTEM_HEADER);
00466 }

void MPEGProgramStreamParser::parseSystemHeader (  )  [private]

Definition at line 468 of file MPEG1or2Demux.cpp.

References Medium::envir(), fUsingSource, StreamParser::get2Bytes(), PARSING_PES_PACKET, setParseState(), StreamParser::skipBytes(), SYSTEM_HEADER_START_CODE, and StreamParser::test4Bytes().

Referenced by parse().

00468                                                 {
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     // The system header was optional.  Look for a PES Packet instead:
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); // we've already seen the system_header_start_code
00483 
00484   unsigned short remaining_header_length = get2Bytes();
00485 
00486   // According to the MPEG-1 and MPEG-2 specs, "remaining_header_length" should be
00487   // at least 6 bytes.  Check this now:
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   // Check for a PES Packet next:
00495   setParseState(PARSING_PES_PACKET);
00496 }

unsigned char MPEGProgramStreamParser::parsePESPacket (  )  [private]

Definition at line 522 of file MPEG1or2Demux.cpp.

References StreamParser::curOffset(), Medium::envir(), MPEG1or2Demux::fHaveUndeliveredData, MPEG1or2Demux::fMPEGversion, MPEG1or2Demux::fOutput, MPEG1or2Demux::OutputDescriptor::frameSize, fUsingSource, StreamParser::get1Byte(), StreamParser::get2Bytes(), StreamParser::get4Bytes(), StreamParser::getBits(), StreamParser::getBytes(), MPEG1or2Demux::OutputDescriptor::isCurrentlyActive, MPEG1or2Demux::OutputDescriptor::isCurrentlyAwaitingData, isPacketStartCode(), MPEG1or2Demux::OutputDescriptor::isPotentiallyReadable, isSpecialStreamId(), MPEG1or2Demux::OutputDescriptor::maxSize, NULL, PARSING_PACK_HEADER, PARSING_PES_PACKET, RAW_PES, READER_NOT_READY, StreamParser::restoreSavedParserState(), MPEG1or2Demux::OutputDescriptor::savedDataHead, MPEG1or2Demux::OutputDescriptor::savedDataTail, MPEG1or2Demux::OutputDescriptor::savedDataTotalSize, setParseState(), StreamParser::skipBytes(), StreamParser::test4Bytes(), MPEG1or2Demux::OutputDescriptor::to, and True.

Referenced by parse().

00522                                                       {
00523 #ifdef DEBUG
00524   fprintf(stderr, "parsing PES packet\n"); fflush(stderr);
00525 #endif
00526   unsigned next4Bytes = test4Bytes();
00527   if (!isPacketStartCode(next4Bytes)) {
00528     // The PES Packet was optional.  Look for a Pack Header instead:
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); // we've already seen the packet_start_code_prefix
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   // Parse over the rest of the header, until we get to the packet data itself.
00571   // This varies depending upon the MPEG version:
00572   if (fUsingSource->fOutput[RAW_PES].isPotentiallyReadable) {
00573     // Hack: We've been asked to return raw PES packets, for every stream:
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) { // stuffing_byte
00587       }
00588       if ((nextByte&0xC0) == 0x40) { // '01'
00589         skipBytes(1);
00590         nextByte = get1Byte();
00591       }
00592       if ((nextByte&0xF0) == 0x20) { // '0010'
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) { // '0011'
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 { // assume MPEG-2
00622     if (!isSpecialStreamId(stream_id)) {
00623       // Fields in the next 3 bytes determine the size of the rest:
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   // The rest of the packet will be the "PES_packet_data_byte"s
00678   // Make sure that "PES_packet_length" was consistent with where we are now:
00679   unsigned char acquiredStreamIdTag = 0;
00680   unsigned currentParserOffset = curOffset();
00681   unsigned bytesSkipped = currentParserOffset - savedParserOffset;
00682   if (stream_id == RAW_PES) {
00683     restoreSavedParserState(); // so we deliver from the beginning of the PES packet
00684     PES_packet_length += 6; // to include the whole of the PES packet
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     // Check whether our using source is interested in this stream type.
00698     // If so, deliver the frame to him:
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       // set out.presentationTime later #####
00718       acquiredStreamIdTag = stream_id;
00719       PES_packet_length -= numBytesToCopy;
00720     } else if (out.isCurrentlyActive) {
00721       // Someone has been reading this stream, but isn't right now.
00722       // We can't deliver this frame until he asks for it, so punt for now.
00723       // The next time he asks for a frame, he'll get it.
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(); // so we read from the beginning next time
00728       fUsingSource->fHaveUndeliveredData = True;
00729       throw READER_NOT_READY;
00730     } else if (out.isPotentiallyReadable &&
00731                out.savedDataTotalSize + PES_packet_length < 1000000 /*limit*/) {
00732       // Someone is interested in this stream, but hasn't begun reading it yet.
00733       // Save this data, so that the reader will get it when he later asks for it.
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   // Check for another PES Packet next:
00751   setParseState(PARSING_PES_PACKET);
00752 #ifdef DEBUG
00753   ++frameCount;
00754 #endif
00755  return acquiredStreamIdTag;
00756 }

Boolean MPEGProgramStreamParser::isSpecialStreamId ( unsigned char  stream_id  )  const [private]

Definition at line 503 of file MPEG1or2Demux.cpp.

References False, MPEG1or2Demux::fMPEGversion, fUsingSource, private_stream_1, private_stream_2, RAW_PES, and True.

Referenced by parsePESPacket().

00503                                                  {
00504   if (stream_id == RAW_PES) return True; // hack
00505 
00506   if (fUsingSource->fMPEGversion == 1) {
00507     return stream_id == private_stream_2;
00508   } else { // assume MPEG-2
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 }

void StreamParser::flushInput (  )  [virtual, inherited]

Reimplemented in MPEG1or2VideoStreamParser, and MPEG4VideoStreamParser.

Definition at line 178 of file StreamParser.cpp.

References StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, StreamParser::fSavedParserIndex, StreamParser::fSavedRemainingUnparsedBits, and StreamParser::fTotNumValidBytes.

Referenced by MPEGVideoStreamFramer::flushInput(), MPEG4VideoStreamParser::flushInput(), MPEG1or2VideoStreamParser::flushInput(), MPEG1or2Demux::flushInput(), MPEG1or2AudioStreamFramer::flushInput(), and AC3AudioStreamFramer::flushInput().

void StreamParser::saveParserState (  )  [protected, inherited]

Definition at line 121 of file StreamParser.cpp.

References StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, StreamParser::fSavedParserIndex, and StreamParser::fSavedRemainingUnparsedBits.

Referenced by MPEG1or2AudioStreamParser::parse(), AC3AudioStreamParser::parseFrame(), MPEGVideoStreamParser::setParseState(), setParseState(), and H263plusVideoStreamParser::setParseState().

void StreamParser::restoreSavedParserState (  )  [protected, virtual, inherited]

Reimplemented in H263plusVideoStreamParser, and MPEGVideoStreamParser.

Definition at line 126 of file StreamParser.cpp.

References StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, StreamParser::fSavedParserIndex, and StreamParser::fSavedRemainingUnparsedBits.

Referenced by StreamParser::afterGettingBytes(), parsePESPacket(), MPEGVideoStreamParser::restoreSavedParserState(), and H263plusVideoStreamParser::restoreSavedParserState().

u_int32_t StreamParser::get4Bytes (  )  [inline, protected, inherited]

Definition at line 46 of file StreamParser.hh.

References StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, and StreamParser::test4Bytes().

Referenced by AC3AudioStreamParser::parseFrame(), MPEG1or2VideoStreamParser::parseGOPHeader(), MPEG4VideoStreamParser::parseGroupOfVideoObjectPlane(), parsePackHeader(), parsePESPacket(), MPEG1or2VideoStreamParser::parsePictureHeader(), MPEG4VideoStreamParser::parseVideoObjectLayer(), MPEG4VideoStreamParser::parseVideoObjectPlane(), MPEG1or2VideoStreamParser::parseVideoSequenceHeader(), MPEG4VideoStreamParser::parseVisualObject(), MPEG4VideoStreamParser::parseVisualObjectSequence(), MPEGVideoStreamParser::saveToNextCode(), and MPEGVideoStreamParser::skipToNextCode().

00046                         { // byte-aligned; returned in big-endian order
00047     u_int32_t result = test4Bytes();
00048     fCurParserIndex += 4;
00049     fRemainingUnparsedBits = 0;
00050 
00051     return result;
00052   }

u_int32_t StreamParser::test4Bytes (  )  [inline, protected, inherited]

Definition at line 53 of file StreamParser.hh.

References StreamParser::ensureValidBytes(), and StreamParser::nextToParse().

Referenced by StreamParser::get4Bytes(), StreamParser::getBits(), MPEG1or2AudioStreamParser::parse(), AC3AudioStreamParser::parseFrame(), MPEG1or2VideoStreamParser::parseGOPHeader(), parsePackHeader(), parsePESPacket(), parseSystemHeader(), MPEG1or2VideoStreamParser::parseVideoSequenceHeader(), and MPEG4VideoStreamParser::parseVisualObjectSequence().

00053                          { // as above, but doesn't advance ptr
00054     ensureValidBytes(4);
00055 
00056     unsigned char const* ptr = nextToParse();
00057     return (ptr[0]<<24)|(ptr[1]<<16)|(ptr[2]<<8)|ptr[3];
00058   }

u_int16_t StreamParser::get2Bytes (  )  [inline, protected, inherited]

Definition at line 60 of file StreamParser.hh.

References StreamParser::ensureValidBytes(), StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, and StreamParser::nextToParse().

Referenced by parsePESPacket(), and parseSystemHeader().

00060                         {
00061     ensureValidBytes(2);
00062 
00063     unsigned char const* ptr = nextToParse();
00064     u_int16_t result = (ptr[0]<<8)|ptr[1];
00065 
00066     fCurParserIndex += 2;
00067     fRemainingUnparsedBits = 0;
00068 
00069     return result;
00070   }

u_int8_t StreamParser::get1Byte (  )  [inline, protected, inherited]

Definition at line 72 of file StreamParser.hh.

References StreamParser::curBank(), StreamParser::ensureValidBytes(), StreamParser::fCurParserIndex, and StreamParser::fRemainingUnparsedBits.

Referenced by MPEG1or2VideoStreamParser::parseGOPHeader(), H263plusVideoStreamParser::parseH263Frame(), parsePackHeader(), parsePESPacket(), MPEG4VideoStreamParser::parseVideoObjectPlane(), MPEG1or2VideoStreamParser::parseVideoSequenceHeader(), MPEG4VideoStreamParser::parseVisualObject(), MPEG4VideoStreamParser::parseVisualObjectSequence(), MPEGVideoStreamParser::saveToNextCode(), and MPEGVideoStreamParser::skipToNextCode().

00072                       { // byte-aligned
00073     ensureValidBytes(1);
00074     fRemainingUnparsedBits = 0;
00075     return curBank()[fCurParserIndex++];
00076   }

void StreamParser::getBytes ( u_int8_t *  to,
unsigned  numBytes 
) [inline, protected, inherited]

Definition at line 78 of file StreamParser.hh.

References StreamParser::ensureValidBytes(), StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, and StreamParser::nextToParse().

Referenced by MPEG1or2AudioStreamParser::parse(), AC3AudioStreamParser::parseFrame(), MPEG4VideoStreamParser::parseGroupOfVideoObjectPlane(), H263plusVideoStreamParser::parseH263Frame(), and parsePESPacket().

00078                                                  {
00079     ensureValidBytes(numBytes);
00080     memmove(to, nextToParse(), numBytes);
00081     fCurParserIndex += numBytes;
00082     fRemainingUnparsedBits = 0;
00083   }

void StreamParser::skipBytes ( unsigned  numBytes  )  [inline, protected, inherited]

Definition at line 84 of file StreamParser.hh.

References StreamParser::ensureValidBytes(), and StreamParser::fCurParserIndex.

Referenced by MPEG1or2AudioStreamParser::parse(), AC3AudioStreamParser::parseFrame(), parsePackHeader(), parsePESPacket(), and parseSystemHeader().

00084                                     {
00085     ensureValidBytes(numBytes);
00086     fCurParserIndex += numBytes;
00087   }

void StreamParser::skipBits ( unsigned  numBits  )  [protected, inherited]

Definition at line 131 of file StreamParser.cpp.

References StreamParser::ensureValidBytes(), StreamParser::fCurParserIndex, and StreamParser::fRemainingUnparsedBits.

Referenced by parsePackHeader().

00131                                             {
00132   if (numBits <= fRemainingUnparsedBits) {
00133     fRemainingUnparsedBits -= numBits;
00134   } else {
00135     numBits -= fRemainingUnparsedBits;
00136 
00137     unsigned numBytesToExamine = (numBits+7)/8; // round up
00138     ensureValidBytes(numBytesToExamine);
00139     fCurParserIndex += numBytesToExamine;
00140 
00141     fRemainingUnparsedBits = 8*numBytesToExamine - numBits;
00142   }
00143 }

unsigned StreamParser::getBits ( unsigned  numBits  )  [protected, inherited]

Definition at line 145 of file StreamParser.cpp.

References StreamParser::fCurParserIndex, StreamParser::fRemainingUnparsedBits, StreamParser::lastParsed(), and StreamParser::test4Bytes().

Referenced by parsePackHeader(), and parsePESPacket().

00145                                                {
00146   if (numBits <= fRemainingUnparsedBits) {
00147     unsigned char lastByte = *lastParsed();
00148     lastByte >>= (fRemainingUnparsedBits - numBits);
00149     fRemainingUnparsedBits -= numBits;
00150 
00151     return (unsigned)lastByte &~ ((~0)<<numBits);
00152   } else {
00153     unsigned char lastByte;
00154     if (fRemainingUnparsedBits > 0) {
00155       lastByte = *lastParsed();
00156     } else {
00157       lastByte = 0;
00158     }
00159 
00160     unsigned remainingBits = numBits - fRemainingUnparsedBits; // > 0
00161 
00162     // For simplicity, read the next 4 bytes, even though we might not
00163     // need all of them here:
00164     unsigned result = test4Bytes();
00165 
00166     result >>= (32 - remainingBits);
00167     result |= (lastByte << remainingBits);
00168     if (numBits < 32) result &=~ ((~0)<<numBits);
00169 
00170     unsigned const numRemainingBytes = (remainingBits+7)/8;
00171     fCurParserIndex += numRemainingBytes;
00172     fRemainingUnparsedBits = 8*numRemainingBytes - remainingBits;
00173 
00174     return result;
00175   }
00176 }

unsigned StreamParser::curOffset (  )  const [inline, protected, inherited]

Definition at line 93 of file StreamParser.hh.

References StreamParser::fCurParserIndex.

Referenced by parsePESPacket().

00093 { return fCurParserIndex; }

unsigned& StreamParser::totNumValidBytes (  )  [inline, protected, inherited]

Definition at line 95 of file StreamParser.hh.

References StreamParser::fTotNumValidBytes.

Referenced by AC3AudioStreamParser::testStreamCode().

00095 { return fTotNumValidBytes; }


Field Documentation

MPEG1or2Demux* MPEGProgramStreamParser::fUsingSource [private]

Definition at line 56 of file MPEG1or2Demux.cpp.

Referenced by isSpecialStreamId(), parsePackHeader(), parsePESPacket(), and parseSystemHeader().

MPEGParseState MPEGProgramStreamParser::fCurrentParseState [private]

Definition at line 57 of file MPEG1or2Demux.cpp.

Referenced by parse(), and setParseState().


The documentation for this class was generated from the following file:
Generated on Tue Oct 7 15:40:02 2008 for live by  doxygen 1.5.2