/**********
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 1 or 2 video elementary stream into
//   frames for: Video_Sequence_Header, GOP_Header, Picture_Header
// Implementation

#include "MPEG1or2VideoStreamFramer.hh"
#include "MPEGVideoStreamParser.hh"
#include <string.h>

////////// MPEG1or2VideoStreamParser definition //////////

// An enum representing the current state of the parser:
enum MPEGParseState {
  PARSING_VIDEO_SEQUENCE_HEADER,
  PARSING_VIDEO_SEQUENCE_HEADER_SEEN_CODE,
  PARSING_GOP_HEADER,
  PARSING_GOP_HEADER_SEEN_CODE,
  PARSING_PICTURE_HEADER,
  PARSING_SLICE
};

#define VSH_MAX_SIZE 1000

class MPEG1or2VideoStreamParser: public MPEGVideoStreamParser {
public:
  MPEG1or2VideoStreamParser(MPEG1or2VideoStreamFramer* usingSource,
			FramedSource* inputSource,
			Boolean iFramesOnly, double vshPeriod);
  virtual ~MPEG1or2VideoStreamParser();

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

private:
  void reset();

  MPEG1or2VideoStreamFramer* usingSource() {
    return (MPEG1or2VideoStreamFramer*)fUsingSource;
  }
  void setParseState(MPEGParseState parseState);

  unsigned parseVideoSequenceHeader(Boolean haveSeenStartCode);
  unsigned parseGOPHeader(Boolean haveSeenStartCode);
  unsigned parsePictureHeader();
  unsigned parseSlice();

private:
  MPEGParseState fCurrentParseState;
  unsigned fPicturesSinceLastGOP;
      // can be used to compute timestamp for a video_sequence_header
  unsigned short fCurPicTemporalReference;
      // used to compute slice timestamp
  unsigned char fCurrentSliceNumber; // set when parsing a slice

  // A saved copy of the most recently seen 'video_sequence_header',
  // in case we need to insert it into the stream periodically:
  unsigned char fSavedVSHBuffer[VSH_MAX_SIZE];
  unsigned fSavedVSHSize;
  double fSavedVSHTimestamp;
  double fVSHPeriod;
  Boolean fIFramesOnly, fSkippingCurrentPicture;

  void saveCurrentVSH();
  Boolean needToUseSavedVSH();
  unsigned useSavedVSH(); // returns the size of the saved VSH
};


////////// MPEG1or2VideoStreamFramer implementation //////////

MPEG1or2VideoStreamFramer::MPEG1or2VideoStreamFramer(UsageEnvironment& env,
						     FramedSource* inputSource,
						     Boolean iFramesOnly,
						     double vshPeriod,
						     Boolean createParser)
  : MPEGVideoStreamFramer(env, inputSource) {
  fParser = createParser
    ? new MPEG1or2VideoStreamParser(this, inputSource,
				    iFramesOnly, vshPeriod)
    : NULL;
}

MPEG1or2VideoStreamFramer::~MPEG1or2VideoStreamFramer() {
}

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

double MPEG1or2VideoStreamFramer::getCurrentPTS() const {
  return fPresentationTime.tv_sec + fPresentationTime.tv_usec/1000000.0;
}

Boolean MPEG1or2VideoStreamFramer::isMPEG1or2VideoStreamFramer() const {
  return True;
}

////////// MPEG1or2VideoStreamParser implementation //////////

MPEG1or2VideoStreamParser
::MPEG1or2VideoStreamParser(MPEG1or2VideoStreamFramer* usingSource,
			FramedSource* inputSource,
			Boolean iFramesOnly, double vshPeriod)
  : MPEGVideoStreamParser(usingSource, inputSource),
    fCurrentParseState(PARSING_VIDEO_SEQUENCE_HEADER),
    fVSHPeriod(vshPeriod), fIFramesOnly(iFramesOnly) {
  reset();
}

MPEG1or2VideoStreamParser::~MPEG1or2VideoStreamParser() {
}

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

void MPEG1or2VideoStreamParser::reset() {
  fPicturesSinceLastGOP = 0;
  fCurPicTemporalReference = 0;
  fCurrentSliceNumber = 0;
  fSavedVSHSize = 0;
  fSkippingCurrentPicture = False;
}

void MPEG1or2VideoStreamParser::flushInput() {
  reset();
  StreamParser::flushInput();
  if (fCurrentParseState != PARSING_VIDEO_SEQUENCE_HEADER) {
    setParseState(PARSING_GOP_HEADER); // start from the next GOP
  }
}

unsigned MPEG1or2VideoStreamParser::parse() {
  try {
    switch (fCurrentParseState) {
    case PARSING_VIDEO_SEQUENCE_HEADER: {
      return parseVideoSequenceHeader(False);
    }
    case PARSING_VIDEO_SEQUENCE_HEADER_SEEN_CODE: {
      return parseVideoSequenceHeader(True);
    }
    case PARSING_GOP_HEADER: {
      return parseGOPHeader(False);
    }
    case PARSING_GOP_HEADER_SEEN_CODE: {
      return parseGOPHeader(True);
    }
    case PARSING_PICTURE_HEADER: {
      return parsePictureHeader();
    }
    case PARSING_SLICE: {
      return parseSlice();
    }
    default: {
      return 0; // shouldn't happen
    }
    }
  } catch (int /*e*/) {
#ifdef DEBUG
    fprintf(stderr, "MPEG1or2VideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
#endif
    return 0;  // the parsing got interrupted
  }
}

void MPEG1or2VideoStreamParser::saveCurrentVSH() {
  unsigned frameSize = curFrameSize();
  if (frameSize > sizeof fSavedVSHBuffer) return; // too big to save

  memmove(fSavedVSHBuffer, fStartOfFrame, frameSize);
  fSavedVSHSize = frameSize;
  fSavedVSHTimestamp = usingSource()->getCurrentPTS();
}

Boolean MPEG1or2VideoStreamParser::needToUseSavedVSH() {
  return usingSource()->getCurrentPTS() > fSavedVSHTimestamp+fVSHPeriod
    && fSavedVSHSize > 0;
}

unsigned MPEG1or2VideoStreamParser::useSavedVSH() {
  unsigned bytesToUse = fSavedVSHSize;
  unsigned maxBytesToUse = fLimit - fStartOfFrame;
  if (bytesToUse > maxBytesToUse) bytesToUse = maxBytesToUse;

  memmove(fStartOfFrame, fSavedVSHBuffer, bytesToUse);

  // Also reset the saved timestamp:
  fSavedVSHTimestamp = usingSource()->getCurrentPTS();

#ifdef DEBUG
  fprintf(stderr, "used saved video_sequence_header (%d bytes)\n", bytesToUse);
#endif
  return bytesToUse;
}

#define VIDEO_SEQUENCE_HEADER_START_CODE 0x000001B3
#define GROUP_START_CODE                 0x000001B8
#define PICTURE_START_CODE               0x00000100
#define SEQUENCE_END_CODE                0x000001B7

static double const frameRateFromCode[] = {
  0.0,          // forbidden
  24000/1001.0, // approx 23.976
  24.0,
  25.0,
  30000/1001.0, // approx 29.97
  30.0,
  50.0,
  60000/1001.0, // approx 59.94
  60.0,
  0.0,          // reserved
  0.0,          // reserved
  0.0,          // reserved
  0.0,          // reserved
  0.0,          // reserved
  0.0,          // reserved
  0.0           // reserved
};

unsigned MPEG1or2VideoStreamParser
::parseVideoSequenceHeader(Boolean haveSeenStartCode) {
#ifdef DEBUG
  fprintf(stderr, "parsing video sequence header\n");
#endif
  unsigned first4Bytes;
  if (!haveSeenStartCode) {
    while ((first4Bytes = test4Bytes()) != VIDEO_SEQUENCE_HEADER_START_CODE) {
#ifdef DEBUG
      fprintf(stderr, "ignoring non video sequence header: 0x%08x\n", first4Bytes);
#endif
      get1Byte(); setParseState(PARSING_VIDEO_SEQUENCE_HEADER);
          // ensures we progress over bad data
    }
    first4Bytes = get4Bytes();
  } else {
    // We've already seen the start code
    first4Bytes = VIDEO_SEQUENCE_HEADER_START_CODE;
  }
  save4Bytes(first4Bytes);

  // Next, extract the size and rate parameters from the next 8 bytes
  unsigned paramWord1 = get4Bytes();
  save4Bytes(paramWord1);
  unsigned next4Bytes = get4Bytes();
#ifdef DEBUG
  unsigned short horizontal_size_value   = (paramWord1&0xFFF00000)>>(32-12);
  unsigned short vertical_size_value     = (paramWord1&0x000FFF00)>>8;
  unsigned char aspect_ratio_information = (paramWord1&0x000000F0)>>4;
#endif
  unsigned char frame_rate_code          = (paramWord1&0x0000000F);
  usingSource()->fFrameRate = frameRateFromCode[frame_rate_code];
#ifdef DEBUG
  unsigned bit_rate_value                = (next4Bytes&0xFFFFC000)>>(32-18);
  unsigned vbv_buffer_size_value         = (next4Bytes&0x00001FF8)>>3;
  fprintf(stderr, "horizontal_size_value: %d, vertical_size_value: %d, aspect_ratio_information: %d, frame_rate_code: %d (=>%f fps), bit_rate_value: %d (=>%d bps), vbv_buffer_size_value: %d\n", horizontal_size_value, vertical_size_value, aspect_ratio_information, frame_rate_code, usingSource()->fFrameRate, bit_rate_value, bit_rate_value*400, vbv_buffer_size_value);
#endif

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

  setParseState((next4Bytes == GROUP_START_CODE)
		? PARSING_GOP_HEADER_SEEN_CODE : PARSING_PICTURE_HEADER);

  // Compute this frame's timestamp by noting how many pictures we've seen
  // since the last GOP header:
  usingSource()->computePresentationTime(fPicturesSinceLastGOP);

  // Save this video_sequence_header, in case we need to insert a copy
  // into the stream later:
  saveCurrentVSH();

  return curFrameSize();
}

unsigned MPEG1or2VideoStreamParser::parseGOPHeader(Boolean haveSeenStartCode) {
  // First check whether we should insert a previously-saved
  // 'video_sequence_header' here:
  if (needToUseSavedVSH()) return useSavedVSH();

#ifdef DEBUG
  fprintf(stderr, "parsing GOP header\n");
#endif
  unsigned first4Bytes;
  if (!haveSeenStartCode) {
    while ((first4Bytes = test4Bytes()) != GROUP_START_CODE) {
#ifdef DEBUG
      fprintf(stderr, "ignoring non GOP start code: 0x%08x\n", first4Bytes);
#endif
      get1Byte(); setParseState(PARSING_GOP_HEADER);
          // ensures we progress over bad data
    }
    first4Bytes = get4Bytes();
  } else {
    // We've already seen the GROUP_START_CODE
    first4Bytes = GROUP_START_CODE;
  }
  save4Bytes(first4Bytes);

  // Next, extract the (25-bit) time code from the next 4 bytes:
  unsigned next4Bytes = get4Bytes();
  unsigned time_code = (next4Bytes&0xFFFFFF80)>>(32-25);
#if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
  Boolean drop_frame_flag     = (time_code&0x01000000) != 0;
#endif
  unsigned time_code_hours    = (time_code&0x00F80000)>>19;
  unsigned time_code_minutes  = (time_code&0x0007E000)>>13;
  unsigned time_code_seconds  = (time_code&0x00000FC0)>>6;
  unsigned time_code_pictures = (time_code&0x0000003F);
#if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
  fprintf(stderr, "time_code: 0x%07x, drop_frame %d, hours %d, minutes %d, seconds %d, pictures %d\n", time_code, drop_frame_flag, time_code_hours, time_code_minutes, time_code_seconds, time_code_pictures);
#endif
#ifdef DEBUG
  Boolean closed_gop  = (next4Bytes&0x00000040) != 0;
  Boolean broken_link = (next4Bytes&0x00000020) != 0;
  fprintf(stderr, "closed_gop: %d, broken_link: %d\n", closed_gop, broken_link);
#endif

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

  // Record the time code:
  usingSource()->setTimeCode(time_code_hours, time_code_minutes,
			     time_code_seconds, time_code_pictures,
			     fPicturesSinceLastGOP);

  fPicturesSinceLastGOP = 0;

  // Compute this frame's timestamp:
  usingSource()->computePresentationTime(0);

  setParseState(PARSING_PICTURE_HEADER);

  return curFrameSize();
}

inline Boolean isSliceStartCode(unsigned fourBytes) {
  if ((fourBytes&0xFFFFFF00) != 0x00000100) return False;

  unsigned char lastByte = fourBytes&0xFF;
  return lastByte <= 0xAF && lastByte >= 1;
}

unsigned MPEG1or2VideoStreamParser::parsePictureHeader() {
#ifdef DEBUG
  fprintf(stderr, "parsing picture header\n");
#endif
  // Note that we've already read the PICTURE_START_CODE
  // Next, extract the temporal reference from the next 4 bytes:
  unsigned next4Bytes = get4Bytes();
  unsigned short temporal_reference = (next4Bytes&0xFFC00000)>>(32-10);
  unsigned char picture_coding_type = (next4Bytes&0x00380000)>>19;
#ifdef DEBUG
  unsigned short vbv_delay          = (next4Bytes&0x0007FFF8)>>3;
  fprintf(stderr, "temporal_reference: %d, picture_coding_type: %d, vbv_delay: %d\n", temporal_reference, picture_coding_type, vbv_delay);
#endif

  fSkippingCurrentPicture = fIFramesOnly && picture_coding_type != 1;
  if (fSkippingCurrentPicture) {
    // Skip all bytes that we see, up until we reach a slice_start_code:
    do {
      skipToNextCode(next4Bytes);
    } while (!isSliceStartCode(next4Bytes));
  } else {
    // Save the PICTURE_START_CODE that we've already read:
    save4Bytes(PICTURE_START_CODE);

    // Copy all bytes that we see, up until we reach a slice_start_code:
    do {
      saveToNextCode(next4Bytes);
    } while (!isSliceStartCode(next4Bytes));
  }

  setParseState(PARSING_SLICE);

  fCurrentSliceNumber = next4Bytes&0xFF;

  // Record the temporal reference:
  fCurPicTemporalReference = temporal_reference;

  // Compute this frame's timestamp:
  usingSource()->computePresentationTime(fCurPicTemporalReference);

  if (fSkippingCurrentPicture) {
    return parse(); // try again, until we get a non-skipped frame
  } else {
    return curFrameSize();
  }
}

unsigned MPEG1or2VideoStreamParser::parseSlice() {
  // Note that we've already read the slice_start_code:
  unsigned next4Bytes = PICTURE_START_CODE|fCurrentSliceNumber;
#ifdef DEBUG_SLICE
  fprintf(stderr, "parsing slice: 0x%08x\n", next4Bytes);
#endif

  if (fSkippingCurrentPicture) {
    // Skip all bytes that we see, up until we reach a code of some sort:
    skipToNextCode(next4Bytes);
  } else {
    // Copy all bytes that we see, up until we reach a code of some sort:
    saveToNextCode(next4Bytes);
  }

  // The next thing to parse depends on the code that we just saw:
  if (isSliceStartCode(next4Bytes)) { // common case
    setParseState(PARSING_SLICE);
    fCurrentSliceNumber = next4Bytes&0xFF;
  } else {
    // Because we don't see any more slices, we are assumed to have ended
    // the current picture:
    ++fPicturesSinceLastGOP;
    ++usingSource()->fPictureCount;
    usingSource()->fPictureEndMarker = True; // HACK #####

    switch (next4Bytes) {
    case SEQUENCE_END_CODE: {
      setParseState(PARSING_VIDEO_SEQUENCE_HEADER);
      break;
    }
    case VIDEO_SEQUENCE_HEADER_START_CODE: {
      setParseState(PARSING_VIDEO_SEQUENCE_HEADER_SEEN_CODE);
      break;
    }
    case GROUP_START_CODE: {
      setParseState(PARSING_GOP_HEADER_SEEN_CODE);
      break;
    }
    case PICTURE_START_CODE: {
      setParseState(PARSING_PICTURE_HEADER);
      break;
    }
    default: {
      usingSource()->envir() << "MPEG1or2VideoStreamParser::parseSlice(): Saw unexpected code "
			    << (void*)next4Bytes << "\n";
      setParseState(PARSING_SLICE); // the safest way to recover...
      break;
    }
    }
  }

  // Compute this frame's timestamp:
  usingSource()->computePresentationTime(fCurPicTemporalReference);

  if (fSkippingCurrentPicture) {
    return parse(); // try again, until we get a non-skipped frame
  } else {
    return curFrameSize();
  }
}
