/**********
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.
// 'ADU' MP3 streams (for improved loss-tolerance)
// Implementation

#include "MP3ADU.hh"
#include "MP3ADUdescriptor.hh"
#include "MP3Internals.hh"
#include <string.h>

#ifdef TEST_LOSS
#include "GroupsockHelper.hh"
#endif

// Segment data structures, used in the implementation below:

#define SegmentBufSize 2000	/* conservatively high */

class Segment {
public:
  unsigned char buf[SegmentBufSize];
  unsigned char* dataStart() { return &buf[descriptorSize]; }
  unsigned frameSize; // if it's a non-ADU frame
  unsigned dataHere(); // if it's a non-ADU frame

  unsigned descriptorSize;
  static unsigned const headerSize;
  unsigned sideInfoSize, aduSize;
  unsigned backpointer;

  struct timeval presentationTime;
  unsigned durationInMicroseconds;
};

unsigned const Segment::headerSize = 4;

#define SegmentQueueSize 20

class SegmentQueue {
public:
  SegmentQueue(Boolean directionIsToADU, Boolean includeADUdescriptors)
    : fDirectionIsToADU(directionIsToADU),
      fIncludeADUdescriptors(includeADUdescriptors) {
    reset();
  }

  Segment s[SegmentQueueSize];

  unsigned headIndex() {return fHeadIndex;}
  Segment& headSegment() {return s[fHeadIndex];}

  unsigned nextFreeIndex() {return fNextFreeIndex;}
  Segment& nextFreeSegment() {return s[fNextFreeIndex];}
  Boolean isEmpty() {return isEmptyOrFull() && totalDataSize() == 0;}
  Boolean isFull() {return isEmptyOrFull() && totalDataSize() > 0;}

  static unsigned nextIndex(unsigned ix) {return (ix+1)%SegmentQueueSize;}
  static unsigned prevIndex(unsigned ix) {return (ix+SegmentQueueSize-1)%SegmentQueueSize;}

  unsigned totalDataSize() {return fTotalDataSize;}

  void enqueueNewSegment(FramedSource* inputSource, FramedSource* usingSource);

  Boolean dequeue();

  Boolean insertDummyBeforeTail(unsigned backpointer);

  void reset() { fHeadIndex = fNextFreeIndex = fTotalDataSize = 0; }

private:
  static void sqAfterGettingSegment(void* clientData,
				    unsigned numBytesRead,
				    unsigned numTruncatedBytes,
				    struct timeval presentationTime,
				    unsigned durationInMicroseconds);

  Boolean sqAfterGettingCommon(Segment& seg, unsigned numBytesRead);
  Boolean isEmptyOrFull() {return headIndex() == nextFreeIndex();}

  unsigned fHeadIndex, fNextFreeIndex, fTotalDataSize;

  // The following is used for asynchronous reads:
  FramedSource* fUsingSource;

  // This tells us whether the direction in which we're being used
  // is MP3->ADU, or vice-versa.  (This flag is used for debugging output.)
  Boolean fDirectionIsToADU;

  // The following is true iff we're used to enqueue incoming
  // ADU frames, and these have an ADU descriptor in front
  Boolean fIncludeADUdescriptors;
};

////////// ADUFromMP3Source //////////

ADUFromMP3Source::ADUFromMP3Source(UsageEnvironment& env,
				   FramedSource* inputSource,
				   Boolean includeADUdescriptors)
  : FramedFilter(env, inputSource),
    fAreEnqueueingMP3Frame(False),
    fSegments(new SegmentQueue(True /* because we're MP3->ADU */,
			       False /*no descriptors in incoming frames*/)),
    fIncludeADUdescriptors(includeADUdescriptors),
    fTotalDataSizeBeforePreviousRead(0), fScale(1), fFrameCounter(0) {
}

ADUFromMP3Source::~ADUFromMP3Source() {
  delete fSegments;
}


char const* ADUFromMP3Source::MIMEtype() const {
  return "audio/MPA-ROBUST";
}

ADUFromMP3Source* ADUFromMP3Source::createNew(UsageEnvironment& env,
                                              FramedSource* inputSource,
                                              Boolean includeADUdescriptors) {
  // The source must be a MPEG audio source:
  if (strcmp(inputSource->MIMEtype(), "audio/MPEG") != 0) {
    env.setResultMsg(inputSource->name(), " is not an MPEG audio source");
    return NULL;
  }

  return new ADUFromMP3Source(env, inputSource, includeADUdescriptors);
}

void ADUFromMP3Source::resetInput() {
  fSegments->reset();
}

Boolean ADUFromMP3Source::setScaleFactor(int scale) {
  if (scale < 1) return False;
  fScale = scale;
  return True;
}

void ADUFromMP3Source::doGetNextFrame() {
  if (!fAreEnqueueingMP3Frame) {
    // Arrange to enqueue a new MP3 frame:
    fTotalDataSizeBeforePreviousRead = fSegments->totalDataSize();
    fAreEnqueueingMP3Frame = True;
    fSegments->enqueueNewSegment(fInputSource, this);
  } else {
    // Deliver an ADU from a previously-read MP3 frame:
    fAreEnqueueingMP3Frame = False;

    if (!doGetNextFrame1()) {
      // An internal error occurred; act as if our source went away:
      handleClosure();
    }
  }
}

Boolean ADUFromMP3Source::doGetNextFrame1() {
  // First, check whether we have enough previously-read data to output an
  // ADU for the last-read MP3 frame:
  unsigned tailIndex;
  Segment* tailSeg;
  Boolean needMoreData;

  if (fSegments->isEmpty()) {
    needMoreData = True;
    tailSeg = NULL; tailIndex = 0; // unneeded, but stops compiler warnings
  } else {
    tailIndex = SegmentQueue::prevIndex(fSegments->nextFreeIndex());
    tailSeg = &(fSegments->s[tailIndex]);

    needMoreData
	  = fTotalDataSizeBeforePreviousRead < tailSeg->backpointer // bp points back too far
      || tailSeg->backpointer + tailSeg->dataHere() < tailSeg->aduSize; // not enough data
  }

  if (needMoreData) {
    // We don't have enough data to output an ADU from the last-read MP3
    // frame, so need to read another one and try again:
    doGetNextFrame();
    return True;
  }

  // Output an ADU from the tail segment:
  fFrameSize = tailSeg->headerSize+tailSeg->sideInfoSize+tailSeg->aduSize;
  fPresentationTime = tailSeg->presentationTime;
  fDurationInMicroseconds = tailSeg->durationInMicroseconds;
  unsigned descriptorSize
    = fIncludeADUdescriptors ? ADUdescriptor::computeSize(fFrameSize) : 0;
#ifdef DEBUG
  fprintf(stderr, "m->a:outputting ADU %d<-%d, nbr:%d, sis:%d, dh:%d, (descriptor size: %d)\n", tailSeg->aduSize, tailSeg->backpointer, fFrameSize, tailSeg->sideInfoSize, tailSeg->dataHere(), descriptorSize);
#endif
  if (descriptorSize + fFrameSize > fMaxSize) {
    envir() << "ADUFromMP3Source::doGetNextFrame1(): not enough room ("
	    << descriptorSize + fFrameSize << ">"
	    << fMaxSize << ")\n";
    fFrameSize = 0;
    return False;
  }

  unsigned char* toPtr = fTo;
  // output the ADU descriptor:
  if (fIncludeADUdescriptors) {
    fFrameSize += ADUdescriptor::generateDescriptor(toPtr, fFrameSize);
  }

  // output header and side info:
  memmove(toPtr, tailSeg->dataStart(),
	  tailSeg->headerSize + tailSeg->sideInfoSize);
  toPtr += tailSeg->headerSize + tailSeg->sideInfoSize;

  // go back to the frame that contains the start of our data:
  unsigned offset = 0;
  unsigned i = tailIndex;
  unsigned prevBytes = tailSeg->backpointer;
  while (prevBytes > 0) {
    i = SegmentQueue::prevIndex(i);
    unsigned dataHere = fSegments->s[i].dataHere();
    if (dataHere < prevBytes) {
      prevBytes -= dataHere;
    } else {
      offset = dataHere - prevBytes;
      break;
    }
  }

  // dequeue any segments that we no longer need:
  while (fSegments->headIndex() != i) {
    fSegments->dequeue(); // we're done with it
  }

  unsigned bytesToUse = tailSeg->aduSize;
  while (bytesToUse > 0) {
    Segment& seg = fSegments->s[i];
    unsigned char* fromPtr
      = &seg.dataStart()[seg.headerSize + seg.sideInfoSize + offset];
    unsigned dataHere = seg.dataHere() - offset;
    unsigned bytesUsedHere = dataHere < bytesToUse ? dataHere : bytesToUse;
    memmove(toPtr, fromPtr, bytesUsedHere);
    bytesToUse -= bytesUsedHere;
    toPtr += bytesUsedHere;
    offset = 0;
    i = SegmentQueue::nextIndex(i);
  }


  if (fFrameCounter++%fScale == 0) {
    // Call our own 'after getting' function.  Because we're not a 'leaf'
    // source, we can call this directly, without risking infinite recursion.
    afterGetting(this);
  } else {
    // Don't use this frame; get another one:
    doGetNextFrame();
  }

  return True;
}


////////// MP3FromADUSource //////////

MP3FromADUSource::MP3FromADUSource(UsageEnvironment& env,
				   FramedSource* inputSource,
				   Boolean includeADUdescriptors)
  : FramedFilter(env, inputSource),
    fAreEnqueueingADU(False),
    fSegments(new SegmentQueue(False /* because we're ADU->MP3 */,
			       includeADUdescriptors)) {
}

MP3FromADUSource::~MP3FromADUSource() {
  delete fSegments;
}

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

MP3FromADUSource* MP3FromADUSource::createNew(UsageEnvironment& env,
					      FramedSource* inputSource,
					      Boolean includeADUdescriptors) {
  // The source must be an MP3 ADU source:
  if (strcmp(inputSource->MIMEtype(), "audio/MPA-ROBUST") != 0) {
    env.setResultMsg(inputSource->name(), " is not an MP3 ADU source");
    return NULL;
  }

  return new MP3FromADUSource(env, inputSource, includeADUdescriptors);
}


void MP3FromADUSource::doGetNextFrame() {
  if (fAreEnqueueingADU) insertDummyADUsIfNecessary();
  fAreEnqueueingADU = False;

  if (needToGetAnADU()) {
    // Before returning a frame, we must enqueue at least one ADU:
#ifdef TEST_LOSS
  NOTE: This code no longer works, because it uses synchronous reads,
  which are no longer supported.
    static unsigned const framesPerPacket = 10;
    static unsigned const frameCount = 0;
    static Boolean packetIsLost;
    while (1) {
      if ((frameCount++)%framesPerPacket == 0) {
	packetIsLost = (our_random()%10 == 0); // simulate 10% packet loss #####
      }

      if (packetIsLost) {
	// Read and discard the next input frame (that would be part of
	// a lost packet):
	Segment dummySegment;
	unsigned numBytesRead;
	struct timeval presentationTime;
	// (this works only if the source can be read synchronously)
	fInputSource->syncGetNextFrame(dummySegment.buf,
				       sizeof dummySegment.buf, numBytesRead,
				       presentationTime);
      } else {
	break; // from while (1)
      }
    }
#endif

    fAreEnqueueingADU = True;
    fSegments->enqueueNewSegment(fInputSource, this);
  } else {
    // Return a frame now:
    generateFrameFromHeadADU();
        // sets fFrameSize, fPresentationTime, and fDurationInMicroseconds

    // Call our own 'after getting' function.  Because we're not a 'leaf'
    // source, we can call this directly, without risking infinite recursion.
    afterGetting(this);
  }
}

Boolean MP3FromADUSource::needToGetAnADU() {
  // Check whether we need to first enqueue a new ADU before we
  // can generate a frame for our head ADU.
  Boolean needToEnqueue = True;

  if (!fSegments->isEmpty()) {
    unsigned index = fSegments->headIndex();
    Segment* seg = &(fSegments->headSegment());
    int const endOfHeadFrame = (int) seg->dataHere();
    unsigned frameOffset = 0;

    while (1) {
      int endOfData = frameOffset - seg->backpointer + seg->aduSize;
      if (endOfData >= endOfHeadFrame) {
	// We already have enough data to generate a frame
	needToEnqueue = False;
	break;
      }

      frameOffset += seg->dataHere();
      index = SegmentQueue::nextIndex(index);
      if (index == fSegments->nextFreeIndex()) break;
      seg = &(fSegments->s[index]);
    }
  }

  return needToEnqueue;
}

void MP3FromADUSource::insertDummyADUsIfNecessary() {
  if (fSegments->isEmpty()) return; // shouldn't happen

  // The tail segment (ADU) is assumed to have been recently
  // enqueued.  If its backpointer would overlap the data
  // of the previous ADU, then we need to insert one or more
  // empty, 'dummy' ADUs ahead of it.  (This situation should occur
  // only if an intermediate ADU was lost.)

  unsigned tailIndex
    = SegmentQueue::prevIndex(fSegments->nextFreeIndex());
  Segment* tailSeg = &(fSegments->s[tailIndex]);

  while (1) {
    unsigned prevADUend; // relative to the start of the new ADU
    if (fSegments->headIndex() != tailIndex) {
      // there is a previous segment
      unsigned prevIndex = SegmentQueue::prevIndex(tailIndex);
      Segment& prevSegment = fSegments->s[prevIndex];
      prevADUend = prevSegment.dataHere() + prevSegment.backpointer;
      if (prevSegment.aduSize > prevADUend) {
	// shouldn't happen if the previous ADU was well-formed
	prevADUend = 0;
      } else {
	prevADUend -= prevSegment.aduSize;
      }
    } else {
      prevADUend = 0;
    }

    if (tailSeg->backpointer > prevADUend) {
      // We need to insert a dummy ADU in front of the tail
#ifdef DEBUG
      fprintf(stderr, "a->m:need to insert a dummy ADU (%d, %d, %d) [%d, %d]\n", tailSeg->backpointer, prevADUend, tailSeg->dataHere(), fSegments->headIndex(), fSegments->nextFreeIndex());
#endif
      tailIndex = fSegments->nextFreeIndex();
      if (!fSegments->insertDummyBeforeTail(prevADUend)) return;
      tailSeg = &(fSegments->s[tailIndex]);
    } else {
      break; // no more dummy ADUs need to be inserted
    }
  }
}

Boolean MP3FromADUSource::generateFrameFromHeadADU() {
    // Output a frame for the head ADU:
    if (fSegments->isEmpty()) return False;
    unsigned index = fSegments->headIndex();
    Segment* seg = &(fSegments->headSegment());
#ifdef DEBUG
    fprintf(stderr, "a->m:outputting frame for %d<-%d (fs %d, dh %d), (descriptorSize: %d)\n", seg->aduSize, seg->backpointer, seg->frameSize, seg->dataHere(), seg->descriptorSize);
#endif
    unsigned char* toPtr = fTo;

    // output header and side info:
    fFrameSize = seg->frameSize;
    fPresentationTime = seg->presentationTime;
    fDurationInMicroseconds = seg->durationInMicroseconds;
    memmove(toPtr, seg->dataStart(), seg->headerSize + seg->sideInfoSize);
    toPtr += seg->headerSize + seg->sideInfoSize;

    // zero out the rest of the frame, in case ADU data doesn't fill it all in
    unsigned bytesToZero = seg->dataHere();
    for (unsigned i = 0; i < bytesToZero; ++i) {
      toPtr[i] = '\0';
    }

    // Fill in the frame with appropriate ADU data from this and
    // subsequent ADUs:
    unsigned frameOffset = 0;
    unsigned toOffset = 0;
    unsigned const endOfHeadFrame = seg->dataHere();

    while (toOffset < endOfHeadFrame) {
      int startOfData = frameOffset - seg->backpointer;
      if (startOfData > (int)endOfHeadFrame) break; // no more ADUs needed

      int endOfData = startOfData + seg->aduSize;
      if (endOfData > (int)endOfHeadFrame) {
	endOfData = endOfHeadFrame;
      }

      unsigned fromOffset;
      if (startOfData <= (int)toOffset) {
	fromOffset = toOffset - startOfData;
	startOfData = toOffset;
	if (endOfData < startOfData) endOfData = startOfData;
      } else {
	fromOffset = 0;

	// we may need some padding bytes beforehand
	unsigned bytesToZero = startOfData - toOffset;
#ifdef DEBUG
	if (bytesToZero > 0) fprintf(stderr, "a->m:outputting %d zero bytes (%d, %d, %d, %d)\n", bytesToZero, startOfData, toOffset, frameOffset, seg->backpointer);
#endif
	toOffset += bytesToZero;
      }

      unsigned char* fromPtr
	= &seg->dataStart()[seg->headerSize + seg->sideInfoSize + fromOffset];
      unsigned bytesUsedHere = endOfData - startOfData;
#ifdef DEBUG
      if (bytesUsedHere > 0) fprintf(stderr, "a->m:outputting %d bytes from %d<-%d\n", bytesUsedHere, seg->aduSize, seg->backpointer);
#endif
      memmove(toPtr + toOffset, fromPtr, bytesUsedHere);
      toOffset += bytesUsedHere;

      frameOffset += seg->dataHere();
      index = SegmentQueue::nextIndex(index);
      if (index == fSegments->nextFreeIndex()) break;
      seg = &(fSegments->s[index]);
    }

    fSegments->dequeue();

    return True;
}


////////// Segment //////////

unsigned Segment::dataHere() {
  int result = frameSize - (headerSize + sideInfoSize);
  if (result < 0) {
    return 0;
  }

  return (unsigned)result;
}

////////// SegmentQueue //////////

void SegmentQueue::enqueueNewSegment(FramedSource* inputSource,
				     FramedSource* usingSource) {
  if (isFull()) {
    usingSource->envir() << "SegmentQueue::enqueueNewSegment() overflow\n";
    usingSource->handleClosure();
    return;
  }

  fUsingSource = usingSource;

  Segment& seg = nextFreeSegment();
  inputSource->getNextFrame(seg.buf, sizeof seg.buf,
			    sqAfterGettingSegment, this,
			    FramedSource::handleClosure, usingSource);
}

void SegmentQueue::sqAfterGettingSegment(void* clientData,
					 unsigned numBytesRead,
					 unsigned /*numTruncatedBytes*/,
					 struct timeval presentationTime,
					 unsigned durationInMicroseconds) {
  SegmentQueue* segQueue = (SegmentQueue*)clientData;
  Segment& seg = segQueue->nextFreeSegment();

  seg.presentationTime = presentationTime;
  seg.durationInMicroseconds = durationInMicroseconds;

  if (segQueue->sqAfterGettingCommon(seg, numBytesRead)) {
#ifdef DEBUG
    char const* direction = segQueue->fDirectionIsToADU ? "m->a" : "a->m";
    fprintf(stderr, "%s:read frame %d<-%d, fs:%d, sis:%d, dh:%d, (descriptor size: %d)\n", direction, seg.aduSize, seg.backpointer, seg.frameSize, seg.sideInfoSize, seg.dataHere(), seg.descriptorSize);
#endif
  }

  // Continue our original calling source where it left off:
  segQueue->fUsingSource->doGetNextFrame();
}

// Common code called after a new segment is enqueued
Boolean SegmentQueue::sqAfterGettingCommon(Segment& seg,
					   unsigned numBytesRead) {
  unsigned char* fromPtr = seg.buf;

  if (fIncludeADUdescriptors) {
    // The newly-read data is assumed to be an ADU with a descriptor
    // in front
    (void)ADUdescriptor::getRemainingFrameSize(fromPtr);
    seg.descriptorSize = (unsigned)(fromPtr-seg.buf);
  } else {
    seg.descriptorSize = 0;
  }

  // parse the MP3-specific info in the frame to get the ADU params
  unsigned hdr;
  MP3SideInfo sideInfo;
  if (!GetADUInfoFromMP3Frame(fromPtr, numBytesRead,
			      hdr, seg.frameSize,
			      sideInfo, seg.sideInfoSize,
			      seg.backpointer, seg.aduSize)) {
    return False;
  }

  // If we've just read an ADU (rather than a regular MP3 frame), then use the
  // entire "numBytesRead" data for the 'aduSize', so that we include any
  // 'ancillary data' that may be present at the end of the ADU:
  if (!fDirectionIsToADU) {
    unsigned newADUSize
      = numBytesRead - seg.descriptorSize - 4/*header size*/ - seg.sideInfoSize;
    if (newADUSize > seg.aduSize) seg.aduSize = newADUSize;
  }
  fTotalDataSize += seg.dataHere();
  fNextFreeIndex = nextIndex(fNextFreeIndex);

  return True;
}

Boolean SegmentQueue::dequeue() {
  if (isEmpty()) {
    fUsingSource->envir() << "SegmentQueue::dequeue(): underflow!\n";
    return False;
  }

  Segment& seg = s[headIndex()];
  fTotalDataSize -= seg.dataHere();
  fHeadIndex = nextIndex(fHeadIndex);
  return True;
}

Boolean SegmentQueue::insertDummyBeforeTail(unsigned backpointer) {
  if (isEmptyOrFull()) return False;

  // Copy the current tail segment to its new position, then modify the
  // old tail segment to be a 'dummy' ADU

  unsigned newTailIndex = nextFreeIndex();
  Segment& newTailSeg = s[newTailIndex];

  unsigned oldTailIndex = prevIndex(newTailIndex);
  Segment& oldTailSeg = s[oldTailIndex];

  newTailSeg = oldTailSeg; // structure copy

  // Begin by setting (replacing) the ADU descriptor of the dummy ADU:
  unsigned char* ptr = oldTailSeg.buf;
  if (fIncludeADUdescriptors) {
    unsigned remainingFrameSize
      = oldTailSeg.headerSize + oldTailSeg.sideInfoSize + 0 /* 0-size ADU */;
    unsigned currentDescriptorSize = oldTailSeg.descriptorSize;

    if (currentDescriptorSize == 2) {
      ADUdescriptor::generateTwoByteDescriptor(ptr, remainingFrameSize);
    } else {
      (void)ADUdescriptor::generateDescriptor(ptr, remainingFrameSize);
    }
  }

  // Then zero out the side info of the dummy frame:
  if (!ZeroOutMP3SideInfo(ptr, oldTailSeg.frameSize,
			  backpointer)) return False;

  unsigned dummyNumBytesRead
    = oldTailSeg.descriptorSize + 4/*header size*/ + oldTailSeg.sideInfoSize;
  return sqAfterGettingCommon(oldTailSeg, dummyNumBytesRead);
}
