/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A filter that breaks up an MPEG-4 video elementary stream into
//   frames for:
// - Visual Object Sequence (VS) Header + Visual Object (VO) Header
//   + Video Object Layer (VOL) Header
// - Group of VOP (GOV) Header
// - VOP frame
// Implementation

#include "MPEG4VideoStreamFramer.hh"
#include "MPEGVideoStreamParser.hh"
#include "MPEG4LATMAudioRTPSource.hh" // for "parseGeneralConfigStr()"
#include <string.h>

////////// MPEG4VideoStreamParser definition //////////

// An enum representing the current state of the parser:
enum MPEGParseState {
  PARSING_VISUAL_OBJECT_SEQUENCE,
  PARSING_VISUAL_OBJECT_SEQUENCE_SEEN_CODE,
  PARSING_VISUAL_OBJECT,
  PARSING_VIDEO_OBJECT_LAYER,
  PARSING_GROUP_OF_VIDEO_OBJECT_PLANE,
  PARSING_VIDEO_OBJECT_PLANE,
  PARSING_VISUAL_OBJECT_SEQUENCE_END_CODE
};

class MPEG4VideoStreamParser: public MPEGVideoStreamParser {
public:
  MPEG4VideoStreamParser(MPEG4VideoStreamFramer* usingSource,
			 FramedSource* inputSource);
  virtual ~MPEG4VideoStreamParser();

private: // redefined virtual functions:
  virtual void flushInput();
  virtual unsigned parse();

private:
  MPEG4VideoStreamFramer* usingSource() {
    return (MPEG4VideoStreamFramer*)fUsingSource;
  }
  void setParseState(MPEGParseState parseState);

  unsigned parseVisualObjectSequence(Boolean haveSeenStartCode = False);
  unsigned parseVisualObject();
  unsigned parseVideoObjectLayer();
  unsigned parseGroupOfVideoObjectPlane();
  unsigned parseVideoObjectPlane();
  unsigned parseVisualObjectSequenceEndCode();

  // These are used for parsing within an already-read frame:
  Boolean getNextFrameBit(u_int8_t& result);
  Boolean getNextFrameBits(unsigned numBits, u_int32_t& result);

  // Which are used by:
  void analyzeVOLHeader();

private:
  MPEGParseState fCurrentParseState;
  unsigned fNumBitsSeenSoFar; // used by the getNextFrameBit*() routines
  u_int32_t vop_time_increment_resolution;
  unsigned fNumVTIRBits;
      // # of bits needed to count to "vop_time_increment_resolution"
  u_int8_t fixed_vop_rate;
  unsigned fixed_vop_time_increment; // used if 'fixed_vop_rate' is set
  unsigned fSecondsSinceLastTimeCode, fTotalTicksSinceLastTimeCode, fPrevNewTotalTicks;
  unsigned fPrevPictureCountDelta;
  Boolean fJustSawTimeCode;
};


////////// MPEG4VideoStreamFramer implementation //////////

MPEG4VideoStreamFramer*
MPEG4VideoStreamFramer::createNew(UsageEnvironment& env,
				  FramedSource* inputSource) {
  // Need to add source type checking here???  #####
  return new MPEG4VideoStreamFramer(env, inputSource);
}

unsigned char* MPEG4VideoStreamFramer
::getConfigBytes(unsigned& numBytes) const {
  numBytes = fNumConfigBytes;
  return fConfigBytes;
}

void MPEG4VideoStreamFramer
::setConfigInfo(u_int8_t profileAndLevelIndication, char const* configStr) {
  fProfileAndLevelIndication = profileAndLevelIndication;

  delete[] fConfigBytes;
  fConfigBytes = parseGeneralConfigStr(configStr, fNumConfigBytes);
}

MPEG4VideoStreamFramer::MPEG4VideoStreamFramer(UsageEnvironment& env,
					       FramedSource* inputSource,
					       Boolean createParser)
  : MPEGVideoStreamFramer(env, inputSource),
    fProfileAndLevelIndication(0),
    fConfigBytes(NULL), fNumConfigBytes(0),
    fNewConfigBytes(NULL), fNumNewConfigBytes(0) {
  fParser = createParser
    ? new MPEG4VideoStreamParser(this, inputSource)
    : NULL;
}

MPEG4VideoStreamFramer::~MPEG4VideoStreamFramer() {
  delete[] fConfigBytes; delete[] fNewConfigBytes;
}

void MPEG4VideoStreamFramer::startNewConfig() {
  delete[] fNewConfigBytes; fNewConfigBytes = NULL;
  fNumNewConfigBytes = 0;
}

void MPEG4VideoStreamFramer
::appendToNewConfig(unsigned char* newConfigBytes, unsigned numNewBytes) {
  // Allocate a new block of memory for the new config bytes:
  unsigned char* configNew
    = new unsigned char[fNumNewConfigBytes + numNewBytes];

  // Copy the old, then the new, config bytes there:
  memmove(configNew, fNewConfigBytes, fNumNewConfigBytes);
  memmove(&configNew[fNumNewConfigBytes], newConfigBytes, numNewBytes);

  delete[] fNewConfigBytes; fNewConfigBytes = configNew;
  fNumNewConfigBytes += numNewBytes;
}

void MPEG4VideoStreamFramer::completeNewConfig() {
  delete[] fConfigBytes; fConfigBytes = fNewConfigBytes;
  fNewConfigBytes = NULL;
  fNumConfigBytes = fNumNewConfigBytes;
  fNumNewConfigBytes = 0;
}

Boolean MPEG4VideoStreamFramer::isMPEG4VideoStreamFramer() const {
  return True;
}

////////// MPEG4VideoStreamParser implementation //////////

MPEG4VideoStreamParser
::MPEG4VideoStreamParser(MPEG4VideoStreamFramer* usingSource,
			 FramedSource* inputSource)
  : MPEGVideoStreamParser(usingSource, inputSource),
    fCurrentParseState(PARSING_VISUAL_OBJECT_SEQUENCE),
    vop_time_increment_resolution(0), fNumVTIRBits(0),
    fixed_vop_rate(0), fixed_vop_time_increment(0),
    fSecondsSinceLastTimeCode(0), fTotalTicksSinceLastTimeCode(0),
    fPrevNewTotalTicks(0), fPrevPictureCountDelta(1), fJustSawTimeCode(False) {
}

MPEG4VideoStreamParser::~MPEG4VideoStreamParser() {
}

void MPEG4VideoStreamParser::setParseState(MPEGParseState parseState) {
  fCurrentParseState = parseState;
  MPEGVideoStreamParser::setParseState();
}

void MPEG4VideoStreamParser::flushInput() {
  fSecondsSinceLastTimeCode = 0;
  fTotalTicksSinceLastTimeCode = 0;
  fPrevNewTotalTicks = 0;
  fPrevPictureCountDelta = 1;

  StreamParser::flushInput();
  if (fCurrentParseState != PARSING_VISUAL_OBJECT_SEQUENCE) {
    setParseState(PARSING_VISUAL_OBJECT_SEQUENCE); // later, change to GOV or VOP? #####
  }
}


unsigned MPEG4VideoStreamParser::parse() {
  try {
    switch (fCurrentParseState) {
    case PARSING_VISUAL_OBJECT_SEQUENCE: {
      return parseVisualObjectSequence();
    }
    case PARSING_VISUAL_OBJECT_SEQUENCE_SEEN_CODE: {
      return parseVisualObjectSequence(True);
    }
    case PARSING_VISUAL_OBJECT: {
      return parseVisualObject();
    }
    case PARSING_VIDEO_OBJECT_LAYER: {
      return parseVideoObjectLayer();
    }
    case PARSING_GROUP_OF_VIDEO_OBJECT_PLANE: {
      return parseGroupOfVideoObjectPlane();
    }
    case PARSING_VIDEO_OBJECT_PLANE: {
      return parseVideoObjectPlane();
    }
    case PARSING_VISUAL_OBJECT_SEQUENCE_END_CODE: {
      return parseVisualObjectSequenceEndCode();
    }
    default: {
      return 0; // shouldn't happen
    }
    }
  } catch (int /*e*/) {
#ifdef DEBUG
    fprintf(stderr, "MPEG4VideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
#endif
    return 0;  // the parsing got interrupted
  }
}

#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0
#define VISUAL_OBJECT_SEQUENCE_END_CODE   0x000001B1
#define GROUP_VOP_START_CODE              0x000001B3
#define VISUAL_OBJECT_START_CODE          0x000001B5
#define VOP_START_CODE                    0x000001B6

unsigned MPEG4VideoStreamParser
::parseVisualObjectSequence(Boolean haveSeenStartCode) {
#ifdef DEBUG
  fprintf(stderr, "parsing VisualObjectSequence\n");
#endif
  usingSource()->startNewConfig();
  u_int32_t first4Bytes;
  if (!haveSeenStartCode) {
    while ((first4Bytes = test4Bytes()) != VISUAL_OBJECT_SEQUENCE_START_CODE) {
#ifdef DEBUG
      fprintf(stderr, "ignoring non VS header: 0x%08x\n", first4Bytes);
#endif
      get1Byte(); setParseState(PARSING_VISUAL_OBJECT_SEQUENCE);
          // ensures we progress over bad data
    }
    first4Bytes = get4Bytes();
  } else {
    // We've already seen the start code
    first4Bytes = VISUAL_OBJECT_SEQUENCE_START_CODE;
  }
  save4Bytes(first4Bytes);

  // The next byte is the "profile_and_level_indication":
  u_int8_t pali = get1Byte();
#ifdef DEBUG
  fprintf(stderr, "profile_and_level_indication: %02x\n", pali);
#endif
  saveByte(pali);
  usingSource()->fProfileAndLevelIndication = pali;

  // Now, copy all bytes that we see, up until we reach
  // a VISUAL_OBJECT_START_CODE:
  u_int32_t next4Bytes = get4Bytes();
  while (next4Bytes != VISUAL_OBJECT_START_CODE) {
    saveToNextCode(next4Bytes);
  }

  setParseState(PARSING_VISUAL_OBJECT);

  // Compute this frame's presentation time:
  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);

  // This header forms part of the 'configuration' information:
  usingSource()->appendToNewConfig(fStartOfFrame, curFrameSize());

  return curFrameSize();
}

static inline Boolean isVideoObjectStartCode(u_int32_t code) {
  return code >= 0x00000100 && code <= 0x0000011F;
}

unsigned MPEG4VideoStreamParser::parseVisualObject() {
#ifdef DEBUG
  fprintf(stderr, "parsing VisualObject\n");
#endif
  // Note that we've already read the VISUAL_OBJECT_START_CODE
  save4Bytes(VISUAL_OBJECT_START_CODE);

  // Next, extract the "visual_object_type" from the next 1 or 2 bytes:
  u_int8_t nextByte = get1Byte(); saveByte(nextByte);
  Boolean is_visual_object_identifier = (nextByte&0x80) != 0;
  u_int8_t visual_object_type;
  if (is_visual_object_identifier) {
#ifdef DEBUG
    fprintf(stderr, "visual_object_verid: 0x%x; visual_object_priority: 0x%x\n", (nextByte&0x78)>>3, (nextByte&0x07));
#endif
    nextByte = get1Byte(); saveByte(nextByte);
    visual_object_type = (nextByte&0xF0)>>4;
  } else {
    visual_object_type = (nextByte&0x78)>>3;
  }
#ifdef DEBUG
  fprintf(stderr, "visual_object_type: 0x%x\n", visual_object_type);
#endif
  // At present, we support only the "Video ID" "visual_object_type" (1)
  if (visual_object_type != 1) {
    usingSource()->envir() << "MPEG4VideoStreamParser::parseVisualObject(): Warning: We don't handle visual_object_type " << visual_object_type << "\n";
  }

  // Now, copy all bytes that we see, up until we reach
  // a video_object_start_code
  u_int32_t next4Bytes = get4Bytes();
  while (!isVideoObjectStartCode(next4Bytes)) {
    saveToNextCode(next4Bytes);
  }
  save4Bytes(next4Bytes);
#ifdef DEBUG
  fprintf(stderr, "saw a video_object_start_code: 0x%08x\n", next4Bytes);
#endif

  setParseState(PARSING_VIDEO_OBJECT_LAYER);

  // Compute this frame's presentation time:
  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);

  // This header forms part of the 'configuration' information:
  usingSource()->appendToNewConfig(fStartOfFrame, curFrameSize());

  return curFrameSize();
}

static inline Boolean isVideoObjectLayerStartCode(u_int32_t code) {
  return code >= 0x00000120 && code <= 0x0000012F;
}

Boolean MPEG4VideoStreamParser::getNextFrameBit(u_int8_t& result) {
  if (fNumBitsSeenSoFar/8 >= curFrameSize()) return False;

  u_int8_t nextByte = fStartOfFrame[fNumBitsSeenSoFar/8];
  result = (nextByte>>(7-fNumBitsSeenSoFar%8))&1;
  ++fNumBitsSeenSoFar;
  return True;
}

Boolean MPEG4VideoStreamParser::getNextFrameBits(unsigned numBits,
						 u_int32_t& result) {
  result = 0;
  for (unsigned i = 0; i < numBits; ++i) {
    u_int8_t nextBit;
    if (!getNextFrameBit(nextBit)) return False;
    result = (result<<1)|nextBit;
  }
  return True;
}

void MPEG4VideoStreamParser::analyzeVOLHeader() {
  // Extract timing information (in particular,
  // "vop_time_increment_resolution") from the VOL Header:
  fNumBitsSeenSoFar = 41;
  do {
    u_int8_t is_object_layer_identifier;
    if (!getNextFrameBit(is_object_layer_identifier)) break;
    if (is_object_layer_identifier) fNumBitsSeenSoFar += 7;

    u_int32_t aspect_ratio_info;
    if (!getNextFrameBits(4, aspect_ratio_info)) break;
    if (aspect_ratio_info == 15 /*extended_PAR*/) fNumBitsSeenSoFar += 16;

    u_int8_t vol_control_parameters;
    if (!getNextFrameBit(vol_control_parameters)) break;
    if (vol_control_parameters) {
      fNumBitsSeenSoFar += 3; // chroma_format; low_delay
      u_int8_t vbw_parameters;
      if (!getNextFrameBit(vbw_parameters)) break;
      if (vbw_parameters) fNumBitsSeenSoFar += 79;
    }

    fNumBitsSeenSoFar += 2; // video_object_layer_shape
    u_int8_t marker_bit;
    if (!getNextFrameBit(marker_bit)) break;
    if (marker_bit != 1) { // sanity check
      usingSource()->envir() << "MPEG4VideoStreamParser::analyzeVOLHeader(): marker_bit 1 not set!\n";
      break;
    }

    if (!getNextFrameBits(16, vop_time_increment_resolution)) break;
#ifdef DEBUG
    fprintf(stderr, "vop_time_increment_resolution: %d\n", vop_time_increment_resolution);
#endif
    if (vop_time_increment_resolution == 0) {
      usingSource()->envir() << "MPEG4VideoStreamParser::analyzeVOLHeader(): vop_time_increment_resolution is zero!\n";
      break;
    }
    // Compute how many bits are necessary to represent this:
    fNumVTIRBits = 0;
    for (unsigned test = vop_time_increment_resolution; test>0; test /= 2) {
      ++fNumVTIRBits;
    }

    if (!getNextFrameBit(marker_bit)) break;
    if (marker_bit != 1) { // sanity check
      usingSource()->envir() << "MPEG4VideoStreamParser::analyzeVOLHeader(): marker_bit 2 not set!\n";
      break;
    }

    if (!getNextFrameBit(fixed_vop_rate)) break;
    if (fixed_vop_rate) {
      // Get the following "fixed_vop_time_increment":
      if (!getNextFrameBits(fNumVTIRBits, fixed_vop_time_increment)) break;
#ifdef DEBUG
      fprintf(stderr, "fixed_vop_time_increment: %d\n", fixed_vop_time_increment);
      if (fixed_vop_time_increment == 0) {
	usingSource()->envir() << "MPEG4VideoStreamParser::analyzeVOLHeader(): fixed_vop_time_increment is zero!\n";
      }
#endif
    }
    // Use "vop_time_increment_resolution" as the 'frame rate'
    // (really, 'tick rate'):
    usingSource()->fFrameRate = (double)vop_time_increment_resolution;
#ifdef DEBUG
    fprintf(stderr, "fixed_vop_rate: %d; 'frame' (really tick) rate: %f\n", fixed_vop_rate, usingSource()->fFrameRate);
#endif

    return;
  } while (0);

  if (fNumBitsSeenSoFar/8 >= curFrameSize()) {
    char errMsg[200];
    sprintf(errMsg, "Not enough bits in VOL header: %d/8 >= %d\n", fNumBitsSeenSoFar, curFrameSize());
    usingSource()->envir() << errMsg;
  }
}

unsigned MPEG4VideoStreamParser::parseVideoObjectLayer() {
#ifdef DEBUG
  fprintf(stderr, "parsing VideoObjectLayer\n");
#endif
  // The first 4 bytes must be a "video_object_layer_start_code".
  // If not, this is a 'short video header', which we currently
  // don't support:
  u_int32_t next4Bytes = get4Bytes();
  if (!isVideoObjectLayerStartCode(next4Bytes)) {
    usingSource()->envir() << "MPEG4VideoStreamParser::parseVideoObjectLayer(): This appears to be a 'short video header', which we currently don't support\n";
  }

  // Now, copy all bytes that we see, up until we reach
  // a GROUP_VOP_START_CODE or a VOP_START_CODE:
  do {
    saveToNextCode(next4Bytes);
  } while (next4Bytes != GROUP_VOP_START_CODE
	   && next4Bytes != VOP_START_CODE);

  analyzeVOLHeader();

  setParseState((next4Bytes == GROUP_VOP_START_CODE)
                ? PARSING_GROUP_OF_VIDEO_OBJECT_PLANE
		: PARSING_VIDEO_OBJECT_PLANE);

  // Compute this frame's presentation time:
  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);

  // This header ends the 'configuration' information:
  usingSource()->appendToNewConfig(fStartOfFrame, curFrameSize());
  usingSource()->completeNewConfig();

  return curFrameSize();
}

unsigned MPEG4VideoStreamParser::parseGroupOfVideoObjectPlane() {
#ifdef DEBUG
  fprintf(stderr, "parsing GroupOfVideoObjectPlane\n");
#endif
  // Note that we've already read the GROUP_VOP_START_CODE
  save4Bytes(GROUP_VOP_START_CODE);

  // Next, extract the (18-bit) time code from the next 3 bytes:
  u_int8_t next3Bytes[3];
  getBytes(next3Bytes, 3);
  saveByte(next3Bytes[0]);saveByte(next3Bytes[1]);saveByte(next3Bytes[2]);
  unsigned time_code
    = (next3Bytes[0]<<10)|(next3Bytes[1]<<2)|(next3Bytes[2]>>6);
  unsigned time_code_hours    = (time_code&0x0003E000)>>13;
  unsigned time_code_minutes  = (time_code&0x00001F80)>>7;
#if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
  Boolean marker_bit          = (time_code&0x00000040) != 0;
#endif
  unsigned time_code_seconds  = (time_code&0x0000003F);
#if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
  fprintf(stderr, "time_code: 0x%05x, hours %d, minutes %d, marker_bit %d, seconds %d\n", time_code, time_code_hours, time_code_minutes, marker_bit, time_code_seconds);
#endif
  fJustSawTimeCode = True;

  // Now, copy all bytes that we see, up until we reach a VOP_START_CODE:
  u_int32_t next4Bytes = get4Bytes();
  while (next4Bytes != VOP_START_CODE) {
    saveToNextCode(next4Bytes);
  }

  // Compute this frame's presentation time:
  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);

  // Record the time code:
  usingSource()->setTimeCode(time_code_hours, time_code_minutes,
                             time_code_seconds, 0, 0);
    // Note: Because the GOV header can appear anywhere (not just at a 1s point), we
    // don't pass "fTotalTicksSinceLastTimeCode" as the "picturesSinceLastGOP" parameter.
  fSecondsSinceLastTimeCode = 0;
  if (fixed_vop_rate) fTotalTicksSinceLastTimeCode = 0;

  setParseState(PARSING_VIDEO_OBJECT_PLANE);

  return curFrameSize();
}

unsigned MPEG4VideoStreamParser::parseVideoObjectPlane() {
#ifdef DEBUG
  fprintf(stderr, "#parsing VideoObjectPlane\n");
#endif
  // Note that we've already read the VOP_START_CODE
  save4Bytes(VOP_START_CODE);

  // Get the "vop_coding_type" from the next byte:
  u_int8_t nextByte = get1Byte(); saveByte(nextByte);
  u_int8_t vop_coding_type = nextByte>>6;

  // Next, get the "modulo_time_base" by counting the '1' bits that follow.
  // We look at the next 32-bits only.  This should be enough in most cases.
  u_int32_t next4Bytes = get4Bytes();
  u_int32_t timeInfo = (nextByte<<(32-6))|(next4Bytes>>6);
  unsigned modulo_time_base = 0;
  u_int32_t mask = 0x80000000;
  while ((timeInfo&mask) != 0) {
    ++modulo_time_base;
    mask >>= 1;
  }
  mask >>= 1;

  // Check the following marker bit:
  if ((timeInfo&mask) == 0) {
    usingSource()->envir() << "MPEG4VideoStreamParser::parseVideoObjectPlane(): marker bit not set!\n";
  }
  mask >>= 1;

  // Then, get the "vop_time_increment".
  // First, make sure we have enough bits left for this:
  if ((mask>>(fNumVTIRBits-1)) == 0) {
    usingSource()->envir() << "MPEG4VideoStreamParser::parseVideoObjectPlane(): 32-bits are not enough to get \"vop_time_increment\"!\n";
  }
  unsigned vop_time_increment = 0;
  for (unsigned i = 0; i < fNumVTIRBits; ++i) {
    vop_time_increment |= timeInfo&mask;
    mask >>= 1;
  }
  while (mask != 0) {
    vop_time_increment >>= 1;
    mask >>= 1;
  }
#ifdef DEBUG
  fprintf(stderr, "vop_coding_type: %d(%c), modulo_time_base: %d, vop_time_increment: %d\n", vop_coding_type, "IPBS"[vop_coding_type], modulo_time_base, vop_time_increment);
#endif

  // Now, copy all bytes that we see, up until we reach a code of some sort:
  saveToNextCode(next4Bytes);

  // Update our counters based on the frame timing information that we saw:
  if (fixed_vop_time_increment > 0) {
    // This is a 'fixed_vop_rate' stream.  Use 'fixed_vop_time_increment':
    usingSource()->fPictureCount += fixed_vop_time_increment;
    if (vop_time_increment > 0 || modulo_time_base > 0) {
      fTotalTicksSinceLastTimeCode += fixed_vop_time_increment;
      // Note: "fSecondsSinceLastTimeCode" and "fPrevNewTotalTicks" are not used.
    }
  } else {
    // Use 'vop_time_increment':
    unsigned newTotalTicks
      = (fSecondsSinceLastTimeCode + modulo_time_base)*vop_time_increment_resolution
      + vop_time_increment;
    if (newTotalTicks == fPrevNewTotalTicks && fPrevNewTotalTicks > 0) {
      // This is apparently a buggy MPEG-4 video stream, because
      // "vop_time_increment" did not change.  Overcome this error,
      // by pretending that it did change.
#ifdef DEBUG
      fprintf(stderr, "Buggy MPEG-4 video stream: \"vop_time_increment\" did not change!\n");
#endif
      // The following assumes that we don't have 'B' frames.  If we do, then TARFU!
      usingSource()->fPictureCount += vop_time_increment;
      fTotalTicksSinceLastTimeCode += vop_time_increment;
      fSecondsSinceLastTimeCode += modulo_time_base;
    } else {
      if (newTotalTicks < fPrevNewTotalTicks && vop_coding_type != 2/*B*/
	  && modulo_time_base == 0 && vop_time_increment == 0 && !fJustSawTimeCode) {
	// This is another kind of buggy MPEG-4 video stream, in which
	// "vop_time_increment" wraps around, but without
	// "modulo_time_base" changing (or just having had a new time code).
	// Overcome this by pretending that "vop_time_increment" *did* wrap around:
#ifdef DEBUG
	fprintf(stderr, "Buggy MPEG-4 video stream: \"vop_time_increment\" wrapped around, but without \"modulo_time_base\" changing!\n");
#endif
	++fSecondsSinceLastTimeCode;
	newTotalTicks += vop_time_increment_resolution;
      }
      fPrevNewTotalTicks = newTotalTicks;
      if (vop_coding_type != 2/*B*/) {
	int pictureCountDelta = newTotalTicks - fTotalTicksSinceLastTimeCode;
	if (pictureCountDelta <= 0) pictureCountDelta = fPrevPictureCountDelta;
	    // ensures that the picture count is always increasing
	usingSource()->fPictureCount += pictureCountDelta;
	fPrevPictureCountDelta = pictureCountDelta;
	fTotalTicksSinceLastTimeCode = newTotalTicks;
	fSecondsSinceLastTimeCode += modulo_time_base;
      }
    }
  }
  fJustSawTimeCode = False; // for next time

  // The next thing to parse depends on the code that we just saw,
  // but we are assumed to have ended the current picture:
  usingSource()->fPictureEndMarker = True; // HACK #####
  switch (next4Bytes) {
  case VISUAL_OBJECT_SEQUENCE_END_CODE: {
    setParseState(PARSING_VISUAL_OBJECT_SEQUENCE_END_CODE);
    break;
  }
  case VISUAL_OBJECT_SEQUENCE_START_CODE: {
    setParseState(PARSING_VISUAL_OBJECT_SEQUENCE_SEEN_CODE);
    break;
  }
  case VISUAL_OBJECT_START_CODE: {
    setParseState(PARSING_VISUAL_OBJECT);
    break;
  }
  case GROUP_VOP_START_CODE: {
    setParseState(PARSING_GROUP_OF_VIDEO_OBJECT_PLANE);
    break;
  }
  case VOP_START_CODE: {
    setParseState(PARSING_VIDEO_OBJECT_PLANE);
    break;
  }
  default: {
    if (isVideoObjectStartCode(next4Bytes)) {
      setParseState(PARSING_VIDEO_OBJECT_LAYER);
    } else if (isVideoObjectLayerStartCode(next4Bytes)){
      // copy all bytes that we see, up until we reach a VOP_START_CODE:
      u_int32_t next4Bytes = get4Bytes();
      while (next4Bytes != VOP_START_CODE) {
	saveToNextCode(next4Bytes);
      }
      setParseState(PARSING_VIDEO_OBJECT_PLANE);
    } else {
      usingSource()->envir() << "MPEG4VideoStreamParser::parseVideoObjectPlane(): Saw unexpected code "
			     << (void*)next4Bytes << "\n";
      setParseState(PARSING_VIDEO_OBJECT_PLANE); // the safest way to recover...
    }
    break;
  }
  }

  // Compute this frame's presentation time:
  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);

  return curFrameSize();
}

unsigned MPEG4VideoStreamParser::parseVisualObjectSequenceEndCode() {
#ifdef DEBUG
  fprintf(stderr, "parsing VISUAL_OBJECT_SEQUENCE_END_CODE\n");
#endif
  // Note that we've already read the VISUAL_OBJECT_SEQUENCE_END_CODE
  save4Bytes(VISUAL_OBJECT_SEQUENCE_END_CODE);

  setParseState(PARSING_VISUAL_OBJECT_SEQUENCE);

  // Treat this as if we had ended a picture:
  usingSource()->fPictureEndMarker = True; // HACK #####

  return curFrameSize();
}
