/**********
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.
// AMR Audio RTP Sources (RFC 4867)
// Implementation

#include "AMRAudioRTPSource.hh"
#include "MultiFramedRTPSource.hh"
#include "BitVector.hh"
#include <string.h>
#include <stdlib.h>

// This source is implemented internally by two separate sources:
// (i) a RTP source for the raw (and possibly interleaved) AMR frames, and
// (ii) a deinterleaving filter that reads from this.
// Define these two new classes here:

class RawAMRRTPSource: public MultiFramedRTPSource {
public:
  static RawAMRRTPSource*
  createNew(UsageEnvironment& env,
	    Groupsock* RTPgs, unsigned char rtpPayloadFormat,
	    Boolean isWideband, Boolean isOctetAligned,
	    Boolean isInterleaved, Boolean CRCsArePresent);

  Boolean isWideband() const { return fIsWideband; }
  unsigned char ILL() const { return fILL; }
  unsigned char ILP() const { return fILP; }
  unsigned TOCSize() const { return fTOCSize; } // total # of frames in the last pkt
  unsigned char* TOC() const { return fTOC; } // FT+Q value for each TOC entry
  unsigned& frameIndex() { return fFrameIndex; } // index of frame-block within pkt
  Boolean& isSynchronized() { return fIsSynchronized; }

private:
  RawAMRRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
		  unsigned char rtpPayloadFormat,
		  Boolean isWideband, Boolean isOctetAligned,
		  Boolean isInterleaved, Boolean CRCsArePresent);
      // called only by createNew()

  virtual ~RawAMRRTPSource();

private:
  // redefined virtual functions:
  virtual Boolean hasBeenSynchronizedUsingRTCP();

  virtual Boolean processSpecialHeader(BufferedPacket* packet,
                                       unsigned& resultSpecialHeaderSize);
  virtual char const* MIMEtype() const;

private:
  Boolean fIsWideband, fIsOctetAligned, fIsInterleaved, fCRCsArePresent;
  unsigned char fILL, fILP;
  unsigned fTOCSize;
  unsigned char* fTOC;
  unsigned fFrameIndex;
  Boolean fIsSynchronized;
};

class AMRDeinterleaver: public AMRAudioSource {
public:
  static AMRDeinterleaver*
  createNew(UsageEnvironment& env,
	    Boolean isWideband, unsigned numChannels, unsigned maxInterleaveGroupSize,
	    RawAMRRTPSource* inputSource);

private:
  AMRDeinterleaver(UsageEnvironment& env,
		   Boolean isWideband, unsigned numChannels,
		   unsigned maxInterleaveGroupSize, RawAMRRTPSource* inputSource);
      // called only by "createNew()"

  virtual ~AMRDeinterleaver();

  static void afterGettingFrame(void* clientData, unsigned frameSize,
				unsigned numTruncatedBytes,
                                struct timeval presentationTime,
				unsigned durationInMicroseconds);
  void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime);

private:
  // Redefined virtual functions:
  void doGetNextFrame();
  virtual void doStopGettingFrames();

private:
  RawAMRRTPSource* fInputSource;
  class AMRDeinterleavingBuffer* fDeinterleavingBuffer;
  Boolean fNeedAFrame;
};


////////// AMRAudioRTPSource implementation //////////

#define MAX_NUM_CHANNELS 20 // far larger than ever expected...
#define MAX_INTERLEAVING_GROUP_SIZE 1000 // far larger than ever expected...

AMRAudioSource*
AMRAudioRTPSource::createNew(UsageEnvironment& env,
			     Groupsock* RTPgs,
			     RTPSource*& resultRTPSource,
			     unsigned char rtpPayloadFormat,
			     Boolean isWideband,
			     unsigned numChannels,
			     Boolean isOctetAligned,
			     unsigned interleaving,
			     Boolean robustSortingOrder,
			     Boolean CRCsArePresent) {
  // Perform sanity checks on the input parameters:
  if (robustSortingOrder) {
    env << "AMRAudioRTPSource::createNew(): 'Robust sorting order' was specified, but we don't yet support this!\n";
    return NULL;
  } else if (numChannels > MAX_NUM_CHANNELS) {
    env << "AMRAudioRTPSource::createNew(): The \"number of channels\" parameter ("
	<< numChannels << ") is much too large!\n";
    return NULL;
  } else if (interleaving > MAX_INTERLEAVING_GROUP_SIZE) {
    env << "AMRAudioRTPSource::createNew(): The \"interleaving\" parameter ("
	<< interleaving << ") is much too large!\n";
    return NULL;
  }

  // 'Bandwidth-efficient mode' precludes some other options:
  if (!isOctetAligned) {
    if (interleaving > 0 || robustSortingOrder || CRCsArePresent) {
      env << "AMRAudioRTPSource::createNew(): 'Bandwidth-efficient mode' was specified, along with interleaving, 'robust sorting order', and/or CRCs, so we assume 'octet-aligned mode' instead.\n";
      isOctetAligned = True;
    }
  }

  Boolean isInterleaved;
  unsigned maxInterleaveGroupSize; // in frames (not frame-blocks)
  if (interleaving > 0) {
    isInterleaved = True;
    maxInterleaveGroupSize = interleaving*numChannels;
  } else {
    isInterleaved = False;
    maxInterleaveGroupSize = numChannels;
  }

  RawAMRRTPSource* rawRTPSource;
  resultRTPSource = rawRTPSource
    = RawAMRRTPSource::createNew(env, RTPgs, rtpPayloadFormat,
				 isWideband, isOctetAligned,
				 isInterleaved, CRCsArePresent);
  if (resultRTPSource == NULL) return NULL;

  AMRDeinterleaver* deinterleaver
    = AMRDeinterleaver::createNew(env, isWideband, numChannels,
				  maxInterleaveGroupSize, rawRTPSource);
  if (deinterleaver == NULL) {
    Medium::close(resultRTPSource);
    resultRTPSource = NULL;
  }

  return deinterleaver;
}


////////// AMRBufferedPacket and AMRBufferedPacketFactory //////////

// A subclass of BufferedPacket, used to separate out AMR frames.

class AMRBufferedPacket: public BufferedPacket {
public:
  AMRBufferedPacket(RawAMRRTPSource& ourSource);
  virtual ~AMRBufferedPacket();

private: // redefined virtual functions
  virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr,
					 unsigned dataSize);
private:
  RawAMRRTPSource& fOurSource;
};

class AMRBufferedPacketFactory: public BufferedPacketFactory {
private: // redefined virtual functions
  virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);
};


///////// RawAMRRTPSource implementation ////////

RawAMRRTPSource*
RawAMRRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
			   unsigned char rtpPayloadFormat,
			   Boolean isWideband, Boolean isOctetAligned,
			   Boolean isInterleaved, Boolean CRCsArePresent) {
  return new RawAMRRTPSource(env, RTPgs, rtpPayloadFormat,
			     isWideband, isOctetAligned,
			     isInterleaved, CRCsArePresent);
}

RawAMRRTPSource
::RawAMRRTPSource(UsageEnvironment& env,
		  Groupsock* RTPgs, unsigned char rtpPayloadFormat,
		  Boolean isWideband, Boolean isOctetAligned,
		  Boolean isInterleaved, Boolean CRCsArePresent)
  : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat,
			 isWideband ? 16000 : 8000,
                         new AMRBufferedPacketFactory),
  fIsWideband(isWideband), fIsOctetAligned(isOctetAligned),
  fIsInterleaved(isInterleaved), fCRCsArePresent(CRCsArePresent),
  fILL(0), fILP(0), fTOCSize(0), fTOC(NULL), fFrameIndex(0), fIsSynchronized(False) {
}

RawAMRRTPSource::~RawAMRRTPSource() {
  delete[] fTOC;
}

#define FT_SPEECH_LOST 14
#define FT_NO_DATA 15

static void unpackBandwidthEfficientData(BufferedPacket* packet,
					 Boolean isWideband); // forward

Boolean RawAMRRTPSource
::processSpecialHeader(BufferedPacket* packet,
		       unsigned& resultSpecialHeaderSize) {
  // If the data is 'bandwidth-efficient', first unpack it so that it's
  // 'octet-aligned':
  if (!fIsOctetAligned) unpackBandwidthEfficientData(packet, fIsWideband);

  unsigned char* headerStart = packet->data();
  unsigned packetSize = packet->dataSize();

  // There's at least a 1-byte header, containing the CMR:
  if (packetSize < 1) return False;
  resultSpecialHeaderSize = 1;

  if (fIsInterleaved) {
    // There's an extra byte, containing the interleave parameters:
    if (packetSize < 2) return False;

    // Get the interleaving parameters, and check them for validity:
    unsigned char const secondByte = headerStart[1];
    fILL = (secondByte&0xF0)>>4;
    fILP = secondByte&0x0F;
    if (fILP > fILL) return False; // invalid
    ++resultSpecialHeaderSize;
  }
#ifdef DEBUG
  fprintf(stderr, "packetSize: %d, ILL: %d, ILP: %d\n", packetSize, fILL, fILP);
#endif
  fFrameIndex = 0; // initially

  // Next, there's a "Payload Table of Contents" (one byte per entry):
  unsigned numFramesPresent = 0, numNonEmptyFramesPresent = 0;
  unsigned tocStartIndex = resultSpecialHeaderSize;
  Boolean F;
  do {
    if (resultSpecialHeaderSize >= packetSize) return False;
    unsigned char const tocByte = headerStart[resultSpecialHeaderSize++];
    F = (tocByte&0x80) != 0;
    unsigned char const FT = (tocByte&0x78) >> 3;
#ifdef DEBUG
    unsigned char Q = (tocByte&0x04)>>2;
    fprintf(stderr, "\tTOC entry: F %d, FT %d, Q %d\n", F, FT, Q);
#endif
    ++numFramesPresent;
    if (FT != FT_SPEECH_LOST && FT != FT_NO_DATA) ++numNonEmptyFramesPresent;
  } while (F);
#ifdef DEBUG
  fprintf(stderr, "TOC contains %d entries (%d non-empty)\n", numFramesPresent, numNonEmptyFramesPresent);
#endif

  // Now that we know the size of the TOC, fill in our copy:
  if (numFramesPresent > fTOCSize) {
    delete[] fTOC;
    fTOC = new unsigned char[numFramesPresent];
  }
  fTOCSize = numFramesPresent;
  for (unsigned i = 0; i < fTOCSize; ++i) {
    unsigned char const tocByte = headerStart[tocStartIndex + i];
    fTOC[i] = tocByte&0x7C; // clear everything except the F and Q fields
  }

  if (fCRCsArePresent) {
    // 'numNonEmptyFramesPresent' CRC bytes will follow.
    // Note: we currently don't check the CRCs for validity #####
    resultSpecialHeaderSize += numNonEmptyFramesPresent;
#ifdef DEBUG
    fprintf(stderr, "Ignoring %d following CRC bytes\n", numNonEmptyFramesPresent);
#endif
    if (resultSpecialHeaderSize > packetSize) return False;
  }
#ifdef DEBUG
  fprintf(stderr, "Total special header size: %d\n", resultSpecialHeaderSize);
#endif

  return True;
}

char const* RawAMRRTPSource::MIMEtype() const {
  return fIsWideband ? "audio/AMR-WB" : "audio/AMR";
}

Boolean RawAMRRTPSource::hasBeenSynchronizedUsingRTCP() {
  return fIsSynchronized;
}


///// AMRBufferedPacket and AMRBufferedPacketFactory implementation

AMRBufferedPacket::AMRBufferedPacket(RawAMRRTPSource& ourSource)
  : fOurSource(ourSource) {
}

AMRBufferedPacket::~AMRBufferedPacket() {
}

// The mapping from the "FT" field to frame size.
// Values of 65535 are invalid.
#define FT_INVALID 65535
static unsigned short const frameBytesFromFT[16] = {
  12, 13, 15, 17,
  19, 20, 26, 31,
  5, FT_INVALID, FT_INVALID, FT_INVALID,
  FT_INVALID, FT_INVALID, FT_INVALID, 0
};
static unsigned short const frameBytesFromFTWideband[16] = {
  17, 23, 32, 36,
  40, 46, 50, 58,
  60, 5, FT_INVALID, FT_INVALID,
  FT_INVALID, FT_INVALID, 0, 0
};

unsigned AMRBufferedPacket::
  nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {
  if (dataSize == 0) return 0; // sanity check

  // The size of the AMR frame is determined by the corresponding 'FT' value
  // in the packet's Table of Contents.
  unsigned const tocIndex = fOurSource.frameIndex();
  if (tocIndex >= fOurSource.TOCSize()) return 0; // sanity check

  unsigned char const tocByte = fOurSource.TOC()[tocIndex];
  unsigned char const FT = (tocByte&0x78) >> 3;
  // ASSERT: FT < 16
  unsigned short frameSize
    = fOurSource.isWideband() ? frameBytesFromFTWideband[FT] : frameBytesFromFT[FT];
  if (frameSize == FT_INVALID) {
    // Strange TOC entry!
    fOurSource.envir() << "AMRBufferedPacket::nextEnclosedFrameSize(): invalid FT: " << FT << "\n";
    frameSize = 0; // This probably messes up the rest of this packet, but...
  }
#ifdef DEBUG
  fprintf(stderr, "AMRBufferedPacket::nextEnclosedFrameSize(): frame #: %d, FT: %d, isWideband: %d => frameSize: %d (dataSize: %d)\n", tocIndex, FT, fOurSource.isWideband(), frameSize, dataSize);
#endif
  ++fOurSource.frameIndex();

  if (dataSize < frameSize) return 0;
  return frameSize;
}

BufferedPacket* AMRBufferedPacketFactory
::createNewPacket(MultiFramedRTPSource* ourSource) {
  return new AMRBufferedPacket((RawAMRRTPSource&)(*ourSource));
}

///////// AMRDeinterleavingBuffer /////////
// (used to implement AMRDeinterleaver)

#define AMR_MAX_FRAME_SIZE 60

class AMRDeinterleavingBuffer {
public:
  AMRDeinterleavingBuffer(unsigned numChannels, unsigned maxInterleaveGroupSize);
  virtual ~AMRDeinterleavingBuffer();

  void deliverIncomingFrame(unsigned frameSize, RawAMRRTPSource* source,
			    struct timeval presentationTime);
  Boolean retrieveFrame(unsigned char* to, unsigned maxSize,
			unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,
			u_int8_t& resultFrameHeader,
			struct timeval& resultPresentationTime,
			Boolean& resultIsSynchronized);

  unsigned char* inputBuffer() { return fInputBuffer; }
  unsigned inputBufferSize() const { return AMR_MAX_FRAME_SIZE; }

private:
  unsigned char* createNewBuffer();

  class FrameDescriptor {
  public:
    FrameDescriptor();
    virtual ~FrameDescriptor();

    unsigned frameSize;
    unsigned char* frameData;
    u_int8_t frameHeader;
    struct timeval presentationTime;
    Boolean fIsSynchronized;
  };

  unsigned fNumChannels, fMaxInterleaveGroupSize;
  FrameDescriptor* fFrames[2];
  unsigned char fIncomingBankId; // toggles between 0 and 1
  unsigned char fIncomingBinMax; // in the incoming bank
  unsigned char fOutgoingBinMax; // in the outgoing bank
  unsigned char fNextOutgoingBin;
  Boolean fHaveSeenPackets;
  u_int16_t fLastPacketSeqNumForGroup;
  unsigned char* fInputBuffer;
  struct timeval fLastRetrievedPresentationTime;
  unsigned fNumSuccessiveSyncedFrames;
  unsigned char fILL;
};


////////// AMRDeinterleaver implementation /////////

AMRDeinterleaver* AMRDeinterleaver
::createNew(UsageEnvironment& env,
	    Boolean isWideband, unsigned numChannels, unsigned maxInterleaveGroupSize,
	    RawAMRRTPSource* inputSource) {
  return new AMRDeinterleaver(env, isWideband, numChannels, maxInterleaveGroupSize, inputSource);
}

AMRDeinterleaver::AMRDeinterleaver(UsageEnvironment& env,
				   Boolean isWideband, unsigned numChannels,
				   unsigned maxInterleaveGroupSize,
				   RawAMRRTPSource* inputSource)
  : AMRAudioSource(env, isWideband, numChannels),
    fInputSource(inputSource), fNeedAFrame(False) {
  fDeinterleavingBuffer
    = new AMRDeinterleavingBuffer(numChannels, maxInterleaveGroupSize);
}

AMRDeinterleaver::~AMRDeinterleaver() {
  delete fDeinterleavingBuffer;
  Medium::close(fInputSource);
}

static unsigned const uSecsPerFrame = 20000; // 20 ms

void AMRDeinterleaver::doGetNextFrame() {
  // First, try getting a frame from the deinterleaving buffer:
  if (fDeinterleavingBuffer->retrieveFrame(fTo, fMaxSize,
					   fFrameSize, fNumTruncatedBytes,
					   fLastFrameHeader, fPresentationTime,
					   fInputSource->isSynchronized())) {

    // Success!
    fNeedAFrame = False;

    fDurationInMicroseconds = uSecsPerFrame;

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

  // No luck, so ask our source for help:
  fNeedAFrame = True;
  if (!fInputSource->isCurrentlyAwaitingData()) {
    fInputSource->getNextFrame(fDeinterleavingBuffer->inputBuffer(),
			       fDeinterleavingBuffer->inputBufferSize(),
			       afterGettingFrame, this,
			       FramedSource::handleClosure, this);
  }
}

void AMRDeinterleaver::doStopGettingFrames() {
  fNeedAFrame = False;
  fInputSource->stopGettingFrames();
}

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

void AMRDeinterleaver
::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime) {
  RawAMRRTPSource* source = (RawAMRRTPSource*)fInputSource;

  // First, put the frame into our deinterleaving buffer:
  fDeinterleavingBuffer->deliverIncomingFrame(frameSize, source, presentationTime);

  // Then, try delivering a frame to the client (if he wants one):
  if (fNeedAFrame) doGetNextFrame();
}


////////// AMRDeinterleavingBuffer implementation /////////

AMRDeinterleavingBuffer
::AMRDeinterleavingBuffer(unsigned numChannels, unsigned maxInterleaveGroupSize)
  : fNumChannels(numChannels), fMaxInterleaveGroupSize(maxInterleaveGroupSize),
    fIncomingBankId(0), fIncomingBinMax(0),
    fOutgoingBinMax(0), fNextOutgoingBin(0),
    fHaveSeenPackets(False), fNumSuccessiveSyncedFrames(0), fILL(0) {
  // Use two banks of descriptors - one for incoming, one for outgoing
  fFrames[0] = new FrameDescriptor[fMaxInterleaveGroupSize];
  fFrames[1] = new FrameDescriptor[fMaxInterleaveGroupSize];
  fInputBuffer = createNewBuffer();
}

AMRDeinterleavingBuffer::~AMRDeinterleavingBuffer() {
  delete[] fInputBuffer;
  delete[] fFrames[0]; delete[] fFrames[1];
}

void AMRDeinterleavingBuffer
::deliverIncomingFrame(unsigned frameSize, RawAMRRTPSource* source,
		       struct timeval presentationTime) {
  fILL = source->ILL();
  unsigned char const ILP = source->ILP();
  unsigned frameIndex = source->frameIndex();
  unsigned short packetSeqNum = source->curPacketRTPSeqNum();

  // First perform a sanity check on the parameters:
  // (This is overkill, as the source should have already done this.)
  if (ILP > fILL || frameIndex == 0) {
#ifdef DEBUG
    fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame() param sanity check failed (%d,%d,%d,%d)\n", frameSize, fILL, ILP, frameIndex);
#endif
    source->envir().internalError();
  }

  --frameIndex; // because it was incremented by the source when this frame was read
  u_int8_t frameHeader;
  if (frameIndex >= source->TOCSize()) { // sanity check
    frameHeader = FT_NO_DATA<<3;
  } else {
    frameHeader = source->TOC()[frameIndex];
  }

  unsigned frameBlockIndex = frameIndex/fNumChannels;
  unsigned frameWithinFrameBlock = frameIndex%fNumChannels;

  // The input "presentationTime" was that of the first frame-block in this
  // packet.  Update it for the current frame:
  unsigned uSecIncrement = frameBlockIndex*(fILL+1)*uSecsPerFrame;
  presentationTime.tv_usec += uSecIncrement;
  presentationTime.tv_sec += presentationTime.tv_usec/1000000;
  presentationTime.tv_usec = presentationTime.tv_usec%1000000;

  // Next, check whether this packet is part of a new interleave group
  if (!fHaveSeenPackets
      || seqNumLT(fLastPacketSeqNumForGroup, packetSeqNum + frameBlockIndex)) {
    // We've moved to a new interleave group
#ifdef DEBUG
    fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): new interleave group\n");
#endif
    fHaveSeenPackets = True;
    fLastPacketSeqNumForGroup = packetSeqNum + fILL - ILP;

    // Switch the incoming and outgoing banks:
    fIncomingBankId ^= 1;
    unsigned char tmp = fIncomingBinMax;
    fIncomingBinMax = fOutgoingBinMax;
    fOutgoingBinMax = tmp;
    fNextOutgoingBin = 0;
  }

  // Now move the incoming frame into the appropriate bin:
  unsigned const binNumber
    = ((ILP + frameBlockIndex*(fILL+1))*fNumChannels + frameWithinFrameBlock)
      % fMaxInterleaveGroupSize; // the % is for sanity
#ifdef DEBUG
  fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): frameIndex %d (%d,%d) put in bank %d, bin %d (%d): size %d, header 0x%02x, presentationTime %lu.%06ld\n", frameIndex, frameBlockIndex, frameWithinFrameBlock, fIncomingBankId, binNumber, fMaxInterleaveGroupSize, frameSize, frameHeader, presentationTime.tv_sec, presentationTime.tv_usec);
#endif
  FrameDescriptor& inBin = fFrames[fIncomingBankId][binNumber];
  unsigned char* curBuffer = inBin.frameData;
  inBin.frameData = fInputBuffer;
  inBin.frameSize = frameSize;
  inBin.frameHeader = frameHeader;
  inBin.presentationTime = presentationTime;
  inBin.fIsSynchronized = ((RTPSource*)source)->RTPSource::hasBeenSynchronizedUsingRTCP();

  if (curBuffer == NULL) curBuffer = createNewBuffer();
  fInputBuffer = curBuffer;

  if (binNumber >= fIncomingBinMax) {
    fIncomingBinMax = binNumber + 1;
  }
}

Boolean AMRDeinterleavingBuffer
::retrieveFrame(unsigned char* to, unsigned maxSize,
		unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,
		u_int8_t& resultFrameHeader,
		struct timeval& resultPresentationTime,
		Boolean& resultIsSynchronized) {

  if (fNextOutgoingBin >= fOutgoingBinMax) return False; // none left

  FrameDescriptor& outBin = fFrames[fIncomingBankId^1][fNextOutgoingBin];
  unsigned char* fromPtr = outBin.frameData;
  unsigned char fromSize = outBin.frameSize;
  outBin.frameSize = 0; // for the next time this bin is used
  resultIsSynchronized = False; // by default; can be changed by:
  if (outBin.fIsSynchronized) {
    // Don't consider the outgoing frame to be synchronized until we've received at least a complete interleave cycle of
    // synchronized frames.  This ensures that the receiver will be getting all synchronized frames from now on.
    if (++fNumSuccessiveSyncedFrames > fILL) {
      resultIsSynchronized = True;
      fNumSuccessiveSyncedFrames = fILL+1; // prevents overflow
    }
  } else {
    fNumSuccessiveSyncedFrames = 0;
  } 

  // Check whether this frame is missing; if so, return a FT_NO_DATA frame:
  if (fromSize == 0) {
    resultFrameHeader = FT_NO_DATA<<3;

    // Compute this erasure frame's presentation time via extrapolation:
    resultPresentationTime = fLastRetrievedPresentationTime;
    resultPresentationTime.tv_usec += uSecsPerFrame;
    if (resultPresentationTime.tv_usec >= 1000000) {
      ++resultPresentationTime.tv_sec;
      resultPresentationTime.tv_usec -= 1000000;
    }
  } else {
    // Normal case - a frame exists:
    resultFrameHeader = outBin.frameHeader;
    resultPresentationTime = outBin.presentationTime;
  }

  fLastRetrievedPresentationTime = resultPresentationTime;

  if (fromSize > maxSize) {
    resultNumTruncatedBytes = fromSize - maxSize;
    resultFrameSize = maxSize;
  } else {
    resultNumTruncatedBytes = 0;
    resultFrameSize = fromSize;
  }
  memmove(to, fromPtr, resultFrameSize);
#ifdef DEBUG
  fprintf(stderr, "AMRDeinterleavingBuffer::retrieveFrame(): from bank %d, bin %d: size %d, header 0x%02x, presentationTime %lu.%06ld\n", fIncomingBankId^1, fNextOutgoingBin, resultFrameSize, resultFrameHeader, resultPresentationTime.tv_sec, resultPresentationTime.tv_usec);
#endif

  ++fNextOutgoingBin;
  return True;
}

unsigned char* AMRDeinterleavingBuffer::createNewBuffer() {
  return new unsigned char[inputBufferSize()];
}

AMRDeinterleavingBuffer::FrameDescriptor::FrameDescriptor()
  : frameSize(0), frameData(NULL) {
}

AMRDeinterleavingBuffer::FrameDescriptor::~FrameDescriptor() {
  delete[] frameData;
}

// Unpack bandwidth-aligned data to octet-aligned:
static unsigned short const frameBitsFromFT[16] = {
  95, 103, 118, 134,
  148, 159, 204, 244,
  39, 0, 0, 0,
  0, 0, 0, 0
};
static unsigned short const frameBitsFromFTWideband[16] = {
  132, 177, 253, 285,
  317, 365, 397, 461,
  477, 40, 0, 0,
  0, 0, 0, 0
};

static void unpackBandwidthEfficientData(BufferedPacket* packet,
					 Boolean isWideband) {
#ifdef DEBUG
  fprintf(stderr, "Unpacking 'bandwidth-efficient' payload (%d bytes):\n", packet->dataSize());
  for (unsigned j = 0; j < packet->dataSize(); ++j) {
    fprintf(stderr, "%02x:", (packet->data())[j]);
  }
  fprintf(stderr, "\n");
#endif
  BitVector fromBV(packet->data(), 0, 8*packet->dataSize());

  unsigned const toBufferSize = 2*packet->dataSize(); // conservatively large
  unsigned char* toBuffer = new unsigned char[toBufferSize];
  unsigned toCount = 0;

  // Begin with the payload header:
  unsigned CMR = fromBV.getBits(4);
  toBuffer[toCount++] = CMR << 4;

  // Then, run through and unpack the TOC entries:
  while (1) {
    unsigned toc = fromBV.getBits(6);
    toBuffer[toCount++] = toc << 2;

    if ((toc&0x20) == 0) break; // the F bit is 0
  }

  // Then, using the TOC data, unpack each frame payload:
  unsigned const tocSize = toCount - 1;
  for (unsigned i = 1; i <= tocSize; ++i) {
    unsigned char tocByte = toBuffer[i];
    unsigned char const FT = (tocByte&0x78) >> 3;
    unsigned short frameSizeBits
      = isWideband ? frameBitsFromFTWideband[FT] : frameBitsFromFT[FT];
    unsigned short frameSizeBytes = (frameSizeBits+7)/8;

    if (frameSizeBits > fromBV.numBitsRemaining()) {
#ifdef DEBUG
      fprintf(stderr, "\tWarning: Unpacking frame %d of %d: want %d bits, but only %d are available!\n", i, tocSize, frameSizeBits, fromBV.numBitsRemaining());
#endif
      break;
    }

    shiftBits(&toBuffer[toCount], 0, // to
	      packet->data(), fromBV.curBitIndex(), // from
	      frameSizeBits // num bits
	      );
    fromBV.skipBits(frameSizeBits);
    toCount += frameSizeBytes;
  }

#ifdef DEBUG
  if (fromBV.numBitsRemaining() > 7) {
    fprintf(stderr, "\tWarning: %d bits remain unused!\n", fromBV.numBitsRemaining());
  }
#endif

  // Finally, replace the current packet data with the unpacked data:
  packet->removePadding(packet->dataSize()); // throws away current packet data
  packet->appendData(toBuffer, toCount);
  delete[] toBuffer;
}
