/**********
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 simplified version of "MPEG1or2VideoStreamFramer" that takes only
// complete, discrete frames (rather than an arbitrary byte stream) as input.
// This avoids the parsing and data copying overhead of the full
// "MPEG1or2VideoStreamFramer".
// Implementation

#include "MPEG1or2VideoStreamDiscreteFramer.hh"

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

MPEG1or2VideoStreamDiscreteFramer
::MPEG1or2VideoStreamDiscreteFramer(UsageEnvironment& env,
                                    FramedSource* inputSource,
                                    Boolean iFramesOnly, double vshPeriod, Boolean leavePresentationTimesUnmodified)
  : MPEG1or2VideoStreamFramer(env, inputSource, iFramesOnly, vshPeriod,
                              False/*don't create a parser*/),
    fLeavePresentationTimesUnmodified(leavePresentationTimesUnmodified),
    fLastNonBFrameTemporal_reference(0),
    fSavedVSHSize(0), fSavedVSHTimestamp(0.0),
    fIFramesOnly(iFramesOnly), fVSHPeriod(vshPeriod) {
  fLastNonBFramePresentationTime.tv_sec = 0;
  fLastNonBFramePresentationTime.tv_usec = 0;
}

MPEG1or2VideoStreamDiscreteFramer::~MPEG1or2VideoStreamDiscreteFramer() {
}

void MPEG1or2VideoStreamDiscreteFramer::doGetNextFrame() {
  // Arrange to read data (which should be a complete MPEG-1 or 2 video frame)
  // from our data source, directly into the client's input buffer.
  // After reading this, we'll do some parsing on the frame.
  fInputSource->getNextFrame(fTo, fMaxSize,
                             afterGettingFrame, this,
                             FramedSource::handleClosure, this);
}

void MPEG1or2VideoStreamDiscreteFramer
::afterGettingFrame(void* clientData, unsigned frameSize,
                    unsigned numTruncatedBytes,
                    struct timeval presentationTime,
                    unsigned durationInMicroseconds) {
  MPEG1or2VideoStreamDiscreteFramer* source
    = (MPEG1or2VideoStreamDiscreteFramer*)clientData;
  source->afterGettingFrame1(frameSize, numTruncatedBytes,
                             presentationTime, durationInMicroseconds);
}

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
};

#define MILLION 1000000

void MPEG1or2VideoStreamDiscreteFramer
::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
                     struct timeval presentationTime,
                     unsigned durationInMicroseconds) {
  // Check that the first 4 bytes are a system code:
  if (frameSize >= 4 && fTo[0] == 0 && fTo[1] == 0 && fTo[2] == 1) {
    fPictureEndMarker = True; // Assume that we have a complete 'picture' here

    u_int8_t nextCode = fTo[3];
    if (nextCode == 0xB3) { // VIDEO_SEQUENCE_HEADER_START_CODE
      // Note the following 'frame rate' code:
      if (frameSize >= 8) {
	u_int8_t frame_rate_code = fTo[7]&0x0F;
	fFrameRate = frameRateFromCode[frame_rate_code];
      }

      // Also, save away this Video Sequence Header, in case we need it later:
      // First, figure out how big it is:
      unsigned vshSize;
      for (vshSize = 4; vshSize < frameSize-3; ++vshSize) {
	if (fTo[vshSize] == 0 && fTo[vshSize+1] == 0 && fTo[vshSize+2] == 1 &&
	    (fTo[vshSize+3] == 0xB8 || fTo[vshSize+3] == 0x00)) break;
      }
      if (vshSize == frameSize-3) vshSize = frameSize; // There was nothing else following it
      if (vshSize <= sizeof fSavedVSHBuffer) {
	memmove(fSavedVSHBuffer, fTo, vshSize);
	fSavedVSHSize = vshSize;
	fSavedVSHTimestamp
	  = presentationTime.tv_sec + presentationTime.tv_usec/(double)MILLION;
      }
    } else if (nextCode == 0xB8) { // GROUP_START_CODE
      // If necessary, insert a saved Video Sequence Header in front of this:
      double pts = presentationTime.tv_sec + presentationTime.tv_usec/(double)MILLION;
      if (pts > fSavedVSHTimestamp + fVSHPeriod &&
	  fSavedVSHSize + frameSize <= fMaxSize) {
	memmove(&fTo[fSavedVSHSize], &fTo[0], frameSize); // make room for the header
	memmove(&fTo[0], fSavedVSHBuffer, fSavedVSHSize); // insert it
	frameSize += fSavedVSHSize;
	fSavedVSHTimestamp = pts;
      }
    }

    unsigned i = 3;
    if (nextCode == 0xB3 /*VIDEO_SEQUENCE_HEADER_START_CODE*/ ||
	nextCode == 0xB8 /*GROUP_START_CODE*/) {
      // Skip to the following PICTURE_START_CODE (if any):
      for (i += 4; i < frameSize; ++i) {
	if (fTo[i] == 0x00 /*PICTURE_START_CODE*/
	    && fTo[i-1] == 1 && fTo[i-2] == 0 && fTo[i-3] == 0) {
	  nextCode = fTo[i];
	  break;
	}
      }
    }

    if (nextCode == 0x00 /*PICTURE_START_CODE*/ && i+2 < frameSize) {
      // Get the 'temporal_reference' and 'picture_coding_type' from the
      // following 2 bytes:
      ++i;
      unsigned short temporal_reference = (fTo[i]<<2)|(fTo[i+1]>>6);
      unsigned char picture_coding_type = (fTo[i+1]&0x38)>>3;

      // If this is not an "I" frame, but we were asked for "I" frames only, then try again:
      if (fIFramesOnly && picture_coding_type != 1) {
	doGetNextFrame();
	return;
      }

      // If this is a "B" frame, then we have to tweak "presentationTime":
      if (!fLeavePresentationTimesUnmodified && picture_coding_type == 3/*B*/
	  && (fLastNonBFramePresentationTime.tv_usec > 0 ||
	      fLastNonBFramePresentationTime.tv_sec > 0)) {
	int trIncrement
            = fLastNonBFrameTemporal_reference - temporal_reference;
	if (trIncrement < 0) trIncrement += 1024; // field is 10 bits in size

	unsigned usIncrement = fFrameRate == 0.0 ? 0
	  : (unsigned)((trIncrement*MILLION)/fFrameRate);
	unsigned secondsToSubtract = usIncrement/MILLION;
	unsigned uSecondsToSubtract = usIncrement%MILLION;

	presentationTime = fLastNonBFramePresentationTime;
	if ((unsigned)presentationTime.tv_usec < uSecondsToSubtract) {
	  presentationTime.tv_usec += MILLION;
	  if (presentationTime.tv_sec > 0) --presentationTime.tv_sec;
	}
	presentationTime.tv_usec -= uSecondsToSubtract;
	if ((unsigned)presentationTime.tv_sec > secondsToSubtract) {
	  presentationTime.tv_sec -= secondsToSubtract;
	} else {
	  presentationTime.tv_sec = presentationTime.tv_usec = 0;
	}
      } else {
	fLastNonBFramePresentationTime = presentationTime;
	fLastNonBFrameTemporal_reference = temporal_reference;
      }
    }
  }

  // ##### Later:
  // - do "iFramesOnly" if requested

  // Complete delivery to the client:
  fFrameSize = frameSize;
  fNumTruncatedBytes = numTruncatedBytes;
  fPresentationTime = presentationTime;
  fDurationInMicroseconds = durationInMicroseconds;
  afterGetting(this);
}
