/**********
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.
// MP3 File Sources
// Implementation

#include "MP3FileSource.hh"
#include "MP3StreamState.hh"
#include "InputFile.hh"

////////// MP3FileSource //////////

MP3FileSource::MP3FileSource(UsageEnvironment& env, FILE* fid)
  : FramedFileSource(env, fid),
    fStreamState(new MP3StreamState(env)) {
}

MP3FileSource::~MP3FileSource() {
  delete fStreamState;
}

char const* MP3FileSource::MIMEtype() const {
  return "audio/MPEG";
}

MP3FileSource* MP3FileSource::createNew(UsageEnvironment& env, char const* fileName) {
  MP3FileSource* newSource = NULL;

  do {
    FILE* fid;

    fid = OpenInputFile(env, fileName);
    if (fid == NULL) break;

    newSource = new MP3FileSource(env, fid);
    if (newSource == NULL) break;

    unsigned fileSize = (unsigned)GetFileSize(fileName, fid);
    newSource->assignStream(fid, fileSize);
    if (!newSource->initializeStream()) break;

    return newSource;
  } while (0);

  Medium::close(newSource);
  return NULL;
}

float MP3FileSource::filePlayTime() const {
  return fStreamState->filePlayTime();
}

unsigned MP3FileSource::fileSize() const {
  return fStreamState->fileSize();
}

void MP3FileSource::setPresentationTimeScale(unsigned scale) {
  fStreamState->setPresentationTimeScale(scale);
}

void MP3FileSource::seekWithinFile(double seekNPT, double streamDuration) {
  float fileDuration = filePlayTime();

  // First, make sure that 0.0 <= seekNPT <= seekNPT + streamDuration <= fileDuration
  if (seekNPT < 0.0) {
    seekNPT = 0.0;
  } else if (seekNPT > fileDuration) {
    seekNPT = fileDuration;
  }
  if (streamDuration < 0.0) {
    streamDuration = 0.0;
  } else if (seekNPT + streamDuration > fileDuration) {
    streamDuration = fileDuration - seekNPT; 
  }

  float seekFraction = (float)seekNPT/fileDuration;
  unsigned seekByteNumber = fStreamState->getByteNumberFromPositionFraction(seekFraction);
  fStreamState->seekWithinFile(seekByteNumber);

  fLimitNumBytesToStream = False; // by default
  if (streamDuration > 0.0) {
    float endFraction = (float)(seekNPT + streamDuration)/fileDuration;
    unsigned endByteNumber = fStreamState->getByteNumberFromPositionFraction(endFraction);
    if (endByteNumber > seekByteNumber) { // sanity check
      fNumBytesToStream = endByteNumber - seekByteNumber;
      fLimitNumBytesToStream = True;
    }
  }
}

void MP3FileSource::getAttributes() const {
  char buffer[200];
  fStreamState->getAttributes(buffer, sizeof buffer);
  envir().setResultMsg(buffer);
}

void MP3FileSource::doGetNextFrame() {
  if (!doGetNextFrame1()) {
    handleClosure();
    return;
  }

  // Switch to another task:
#if defined(__WIN32__) || defined(_WIN32)
  // HACK: liveCaster/lc uses an implementation of scheduleDelayedTask()
  // that performs very badly (chewing up lots of CPU time, apparently polling)
  // on Windows.  Until this is fixed, we just call our "afterGetting()"
  // function directly.  This avoids infinite recursion, as long as our sink
  // is discontinuous, which is the case for the RTP sink that liveCaster/lc
  // uses. #####
  afterGetting(this);
#else
  nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
				(TaskFunc*)afterGetting, this);
#endif
}

Boolean MP3FileSource::doGetNextFrame1() {
  if (fLimitNumBytesToStream && fNumBytesToStream == 0) return False; // we've already streamed as much as we were asked for

  if (!fHaveJustInitialized) {
    if (fStreamState->findNextHeader(fPresentationTime) == 0) return False;
  } else {
    fPresentationTime = fFirstFramePresentationTime;
    fHaveJustInitialized = False;
  }

  if (!fStreamState->readFrame(fTo, fMaxSize, fFrameSize, fDurationInMicroseconds)) {
    char tmp[200];
    sprintf(tmp,
	    "Insufficient buffer size %d for reading MPEG audio frame (needed %d)\n",
	    fMaxSize, fFrameSize);
    envir().setResultMsg(tmp);
    fFrameSize = fMaxSize;
    return False;
  }
  if (fNumBytesToStream > fFrameSize) fNumBytesToStream -= fFrameSize; else fNumBytesToStream = 0;

  return True;
}

void MP3FileSource::assignStream(FILE* fid, unsigned fileSize) {
  fStreamState->assignStream(fid, fileSize);
}


Boolean MP3FileSource::initializeStream() {
  // Make sure the file has an appropriate header near the start:
  if (fStreamState->findNextHeader(fFirstFramePresentationTime) == 0) {
      envir().setResultMsg("not an MPEG audio file");
      return False;
  }

  fStreamState->checkForXingHeader(); // in case this is a VBR file

  fHaveJustInitialized = True;
  fLimitNumBytesToStream = False;
  fNumBytesToStream = 0;

  // Hack: It's possible that our environment's 'result message' has been
  // reset within this function, so set it again to our name now:
  envir().setResultMsg(name());
  return True;
}
