/**********
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 class that encapsulates MPEG-2 Transport Stream 'index files'/
// These index files are used to implement 'trick play' operations
// (seek-by-time, fast forward, reverse play) on Transport Stream files.
//
// Implementation

#include "MPEG2TransportStreamIndexFile.hh"
#include "InputFile.hh"

MPEG2TransportStreamIndexFile
::MPEG2TransportStreamIndexFile(UsageEnvironment& env, char const* indexFileName)
  : Medium(env),
    fFileName(strDup(indexFileName)), fFid(NULL), fMPEGVersion(0), fCurrentIndexRecordNum(0),
    fCachedPCR(0.0f), fCachedTSPacketNumber(0), fNumIndexRecords(0) {
  // Get the file size, to determine how many index records it contains:
  u_int64_t indexFileSize = GetFileSize(indexFileName, NULL);
  if (indexFileSize % INDEX_RECORD_SIZE != 0) {
    env << "Warning: Size of the index file \"" << indexFileName
 	<< "\" (" << (unsigned)indexFileSize
	<< ") is not a multiple of the index record size ("
	<< INDEX_RECORD_SIZE << ")\n";
  }
  fNumIndexRecords = (unsigned long)(indexFileSize/INDEX_RECORD_SIZE);
}

MPEG2TransportStreamIndexFile* MPEG2TransportStreamIndexFile
::createNew(UsageEnvironment& env, char const* indexFileName) {
  if (indexFileName == NULL) return NULL;
  MPEG2TransportStreamIndexFile* indexFile
    = new MPEG2TransportStreamIndexFile(env, indexFileName);

  // Reject empty or non-existent index files:
  if (indexFile->getPlayingDuration() == 0.0f) {
    delete indexFile;
    indexFile = NULL;
  }

  return indexFile;
}

MPEG2TransportStreamIndexFile::~MPEG2TransportStreamIndexFile() {
  closeFid();
  delete[] fFileName;
}

void MPEG2TransportStreamIndexFile
::lookupTSPacketNumFromNPT(float& npt, unsigned long& tsPacketNumber,
			   unsigned long& indexRecordNumber) {
  if (npt <= 0.0 || fNumIndexRecords == 0) { // Fast-track a common case:
    npt = 0.0f;
    tsPacketNumber = indexRecordNumber = 0;
    return;
  }

  // If "npt" is the same as the one that we last looked up, return its cached result:
  if (npt == fCachedPCR) {
    tsPacketNumber = fCachedTSPacketNumber;
    indexRecordNumber = fCachedIndexRecordNumber;
    return;
  }

  // Search for the pair of neighboring index records whose PCR values span "npt".
  // Use the 'regula-falsi' method.
  Boolean success = False;
  unsigned long ixFound = 0;
  do {
    unsigned long ixLeft = 0, ixRight = fNumIndexRecords-1;
    float pcrLeft = 0.0f, pcrRight;
    if (!readIndexRecord(ixRight)) break;
    pcrRight = pcrFromBuf();
    if (npt > pcrRight) npt = pcrRight;
        // handle "npt" too large by seeking to the last frame of the file

    while (ixRight-ixLeft > 1 && pcrLeft < npt && npt <= pcrRight) {
      unsigned long ixNew = ixLeft
	+ (unsigned long)(((npt-pcrLeft)/(pcrRight-pcrLeft))*(ixRight-ixLeft));
      if (ixNew == ixLeft || ixNew == ixRight) {
	// use bisection instead:
	ixNew = (ixLeft+ixRight)/2;
      }
      if (!readIndexRecord(ixNew)) break;
      float pcrNew = pcrFromBuf();
      if (pcrNew < npt) {
	pcrLeft = pcrNew;
	ixLeft = ixNew;
      } else {
	pcrRight = pcrNew;
	ixRight = ixNew;
      }
    }
    if (ixRight-ixLeft > 1 || npt <= pcrLeft || npt > pcrRight) break; // bad PCR values in index file?

    ixFound = ixRight;
    // "Rewind' until we reach the start of a Video Sequence or GOP header:
    success = rewindToCleanPoint(ixFound);
  } while (0);

  if (success && readIndexRecord(ixFound)) {
    // Return (and cache) information from record "ixFound":
    npt = fCachedPCR = pcrFromBuf();
    tsPacketNumber = fCachedTSPacketNumber = tsPacketNumFromBuf();
    indexRecordNumber = fCachedIndexRecordNumber = ixFound;
  } else {
    // An error occurred: Return the default values, for npt == 0:
    npt = 0.0f;
    tsPacketNumber = indexRecordNumber = 0;
  }
  closeFid();
}

void MPEG2TransportStreamIndexFile
::lookupPCRFromTSPacketNum(unsigned long& tsPacketNumber, Boolean reverseToPreviousCleanPoint,
			   float& pcr, unsigned long& indexRecordNumber) {
  if (tsPacketNumber == 0 || fNumIndexRecords == 0) { // Fast-track a common case:
    pcr = 0.0f;
    indexRecordNumber = 0;
    return;
  }

  // If "tsPacketNumber" is the same as the one that we last looked up, return its cached result:
  if (tsPacketNumber == fCachedTSPacketNumber) {
    pcr = fCachedPCR;
    indexRecordNumber = fCachedIndexRecordNumber;
    return;
  }

  // Search for the pair of neighboring index records whose TS packet #s span "tsPacketNumber".
  // Use the 'regula-falsi' method.
  Boolean success = False;
  unsigned long ixFound = 0;
  do {
    unsigned long ixLeft = 0, ixRight = fNumIndexRecords-1;
    unsigned long tsLeft = 0, tsRight;
    if (!readIndexRecord(ixRight)) break;
    tsRight = tsPacketNumFromBuf();
    if (tsPacketNumber > tsRight) tsPacketNumber = tsRight;
        // handle "tsPacketNumber" too large by seeking to the last frame of the file

    while (ixRight-ixLeft > 1 && tsLeft < tsPacketNumber && tsPacketNumber <= tsRight) {
      unsigned long ixNew = ixLeft
	+ (unsigned long)(((tsPacketNumber-tsLeft)/(tsRight-tsLeft))*(ixRight-ixLeft));
      if (ixNew == ixLeft || ixNew == ixRight) {
	// Use bisection instead:
	ixNew = (ixLeft+ixRight)/2;
      }
      if (!readIndexRecord(ixNew)) break;
      unsigned long tsNew = tsPacketNumFromBuf();
      if (tsNew < tsPacketNumber) {
	tsLeft = tsNew;
	ixLeft = ixNew;
      } else {
	tsRight = tsNew;
	ixRight = ixNew;
      }
    }
    if (ixRight-ixLeft > 1 || tsPacketNumber <= tsLeft || tsPacketNumber > tsRight) break; // bad PCR values in index file?

    ixFound = ixRight;
    if (reverseToPreviousCleanPoint) {
      // "Rewind' until we reach the start of a Video Sequence or GOP header:
      success = rewindToCleanPoint(ixFound);
    } else {
      success = True;
    }
  } while (0);

  if (success && readIndexRecord(ixFound)) {
    // Return (and cache) information from record "ixFound":
    pcr = fCachedPCR = pcrFromBuf();
    fCachedTSPacketNumber = tsPacketNumFromBuf();
    if (reverseToPreviousCleanPoint) tsPacketNumber = fCachedTSPacketNumber;
    indexRecordNumber = fCachedIndexRecordNumber = ixFound;
  } else {
    // An error occurred: Return the default values, for tsPacketNumber == 0:
    pcr = 0.0f;
    indexRecordNumber = 0;
  }
  closeFid();
}

Boolean MPEG2TransportStreamIndexFile
::readIndexRecordValues(unsigned long indexRecordNum,
			unsigned long& transportPacketNum, u_int8_t& offset,
			u_int8_t& size, float& pcr, u_int8_t& recordType) {
  if (!readIndexRecord(indexRecordNum)) return False;

  transportPacketNum = tsPacketNumFromBuf();
  offset = offsetFromBuf();
  size = sizeFromBuf();
  pcr = pcrFromBuf();
  recordType = recordTypeFromBuf();
  return True;
}

float MPEG2TransportStreamIndexFile::getPlayingDuration() {
  if (fNumIndexRecords == 0 || !readOneIndexRecord(fNumIndexRecords-1)) return 0.0f;

  return pcrFromBuf();
}

int MPEG2TransportStreamIndexFile::mpegVersion() {
  if (fMPEGVersion != 0) return fMPEGVersion; // we already know it

  // Read the first index record, and figure out the MPEG version from its type:
  if (!readOneIndexRecord(0)) return 0; // unknown; perhaps the indecx file is empty?	

  setMPEGVersionFromRecordType(recordTypeFromBuf());
  return fMPEGVersion;
}

Boolean MPEG2TransportStreamIndexFile::openFid() {
  if (fFid == NULL && fFileName != NULL) {
    if ((fFid = OpenInputFile(envir(), fFileName)) != NULL) {
      fCurrentIndexRecordNum = 0;
    }
  }

  return fFid != NULL;
}

Boolean MPEG2TransportStreamIndexFile::seekToIndexRecord(unsigned long indexRecordNumber) {
  if (!openFid()) return False;

  if (indexRecordNumber == fCurrentIndexRecordNum) return True; // we're already there

  if (SeekFile64(fFid, (int64_t)(indexRecordNumber*INDEX_RECORD_SIZE), SEEK_SET) != 0) return False;
  fCurrentIndexRecordNum = indexRecordNumber;
  return True;
}

Boolean MPEG2TransportStreamIndexFile::readIndexRecord(unsigned long indexRecordNum) {
  do {
    if (!seekToIndexRecord(indexRecordNum)) break;
    if (fread(fBuf, INDEX_RECORD_SIZE, 1, fFid) != 1) break;
    ++fCurrentIndexRecordNum;

    return True;
  } while (0);

  return False; // an error occurred
}

Boolean MPEG2TransportStreamIndexFile::readOneIndexRecord(unsigned long indexRecordNum) {
  Boolean result = readIndexRecord(indexRecordNum);
  closeFid();

  return result;
}

void MPEG2TransportStreamIndexFile::closeFid() {
  if (fFid != NULL) {
    CloseInputFile(fFid);
    fFid = NULL;
  }
}

float MPEG2TransportStreamIndexFile::pcrFromBuf() {
  unsigned pcr_int = (fBuf[5]<<16) | (fBuf[4]<<8) | fBuf[3];
  u_int8_t pcr_frac = fBuf[6];
  return pcr_int + pcr_frac/256.0f;
}

unsigned long MPEG2TransportStreamIndexFile::tsPacketNumFromBuf() {
  return (fBuf[10]<<24) | (fBuf[9]<<16) | (fBuf[8]<<8) | fBuf[7];
}

void MPEG2TransportStreamIndexFile::setMPEGVersionFromRecordType(u_int8_t recordType) {
  if (fMPEGVersion != 0) return; // we already know it
 
  u_int8_t const recordTypeWithoutStartBit = recordType&~0x80;
  if (recordTypeWithoutStartBit >= 1 && recordTypeWithoutStartBit <= 4) fMPEGVersion = 2;
  else if (recordTypeWithoutStartBit >= 5 && recordTypeWithoutStartBit <= 10) fMPEGVersion = 5;
      // represents H.264
  else if (recordTypeWithoutStartBit >= 11 && recordTypeWithoutStartBit <= 16) fMPEGVersion = 6;
      // represents H.265
}

Boolean MPEG2TransportStreamIndexFile::rewindToCleanPoint(unsigned long&ixFound) {
  Boolean success = False; // until we learn otherwise

  while (ixFound > 0) {
    if (!readIndexRecord(ixFound)) break;

    u_int8_t recordType = recordTypeFromBuf();
    setMPEGVersionFromRecordType(recordType);

    // A 'clean point' is the start of a 'frame' from which a decoder can cleanly resume
    // handling the stream.  For H.264, this is a SPS.  For H.265, this is a VPS.
    // For MPEG-2, this is a Video Sequence Header, or a GOP. 

    if ((recordType&0x80) != 0) { // This is the start of a 'frame'
      recordType &=~ 0x80; // remove the 'start of frame' bit
      if (fMPEGVersion == 5) { // H.264
        if (recordType == 5/*SPS*/) {
	  success = True;
	  break;
	}
      } else if (fMPEGVersion == 6) { // H.265
        if (recordType == 11/*VPS*/) {
	  success = True;
	  break;
	}
      } else { // MPEG-1, 2, or 4
	if (recordType == 1/*VSH*/) {
	  success = True;
	  break;
	} else if (recordType == 2/*GOP*/) {
	  // Hack: If the preceding record is for a Video Sequence Header, then use it instead:
	  unsigned long newIxFound = ixFound;

	  while (--newIxFound > 0) {
	    if (!readIndexRecord(newIxFound)) break;
	    recordType = recordTypeFromBuf();
	    if ((recordType&0x7F) != 1) break; // not a Video Sequence Header
	    if ((recordType&0x80) != 0) { // this is the start of the VSH; use it
	      ixFound = newIxFound;
	      break;
	    }
	  }
        }
        success = True;
        break;
      }
    }

    // Keep checking, from the previous record:
    --ixFound;
  }
  if (ixFound == 0) success = True; // use record 0 anyway

  return success;
}
