/**********
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.
// MPEG-4 audio, using LATM multiplexing
// Implementation

#include "MPEG4LATMAudioRTPSource.hh"

////////// LATMBufferedPacket and LATMBufferedPacketFactory //////////

class LATMBufferedPacket: public BufferedPacket {
public:
  LATMBufferedPacket(Boolean includeLATMDataLengthField);
  virtual ~LATMBufferedPacket();

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

private:
  Boolean fIncludeLATMDataLengthField;
};

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

///////// MPEG4LATMAudioRTPSource implementation ////////

MPEG4LATMAudioRTPSource*
MPEG4LATMAudioRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
				   unsigned char rtpPayloadFormat,
				   unsigned rtpTimestampFrequency) {
  return new MPEG4LATMAudioRTPSource(env, RTPgs, rtpPayloadFormat,
				     rtpTimestampFrequency);
}

MPEG4LATMAudioRTPSource
::MPEG4LATMAudioRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
			  unsigned char rtpPayloadFormat,
			  unsigned rtpTimestampFrequency)
  : MultiFramedRTPSource(env, RTPgs,
			 rtpPayloadFormat, rtpTimestampFrequency,
			 new LATMBufferedPacketFactory),
    fIncludeLATMDataLengthField(True) {
}

MPEG4LATMAudioRTPSource::~MPEG4LATMAudioRTPSource() {
}

void MPEG4LATMAudioRTPSource::omitLATMDataLengthField() {
  fIncludeLATMDataLengthField = False;
}

Boolean MPEG4LATMAudioRTPSource
::processSpecialHeader(BufferedPacket* packet,
		       unsigned& resultSpecialHeaderSize) {
  fCurrentPacketBeginsFrame = fCurrentPacketCompletesFrame;
          // whether the *previous* packet ended a frame

  // The RTP "M" (marker) bit indicates the last fragment of a frame:
  fCurrentPacketCompletesFrame = packet->rtpMarkerBit();

  // There is no special header
  resultSpecialHeaderSize = 0;
  return True;
}

char const* MPEG4LATMAudioRTPSource::MIMEtype() const {
  return "audio/MP4A-LATM";
}


////////// LATMBufferedPacket and LATMBufferedPacketFactory implementation

LATMBufferedPacket::LATMBufferedPacket(Boolean includeLATMDataLengthField)
  : fIncludeLATMDataLengthField(includeLATMDataLengthField) {
}

LATMBufferedPacket::~LATMBufferedPacket() {
}

unsigned LATMBufferedPacket
::nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {
  // Look at the LATM data length byte(s), to determine the size
  // of the LATM payload.
  unsigned resultFrameSize = 0;
  unsigned i;
  for (i = 0; i < dataSize; ++i) {
    resultFrameSize += framePtr[i];
    if (framePtr[i] != 0xFF) break;
  }
  ++i;
  if (fIncludeLATMDataLengthField) {
    resultFrameSize += i;
  } else {
    framePtr += i;
    dataSize -= i;
  }

  return (resultFrameSize <= dataSize) ? resultFrameSize : dataSize;
}

BufferedPacket* LATMBufferedPacketFactory
::createNewPacket(MultiFramedRTPSource* ourSource) {
  MPEG4LATMAudioRTPSource* source = (MPEG4LATMAudioRTPSource*)ourSource;
  return new LATMBufferedPacket(source->returnedFrameIncludesLATMDataLengthField());
}


////////// parseStreamMuxConfigStr() implementation //////////

static Boolean getNibble(char const*& configStr,
			 unsigned char& resultNibble) {
  char c = configStr[0];
  if (c == '\0') return False; // we've reached the end

  if (c >= '0' && c <= '9') {
    resultNibble = c - '0';
  } else if (c >= 'A' && c <= 'F') {
    resultNibble = 10 + c - 'A';
  } else if (c >= 'a' && c <= 'f') {
    resultNibble = 10 + c - 'a';
  } else {
    return False;
  }

  ++configStr; // move to the next nibble
  return True;
}

static Boolean getByte(char const*& configStr, unsigned char& resultByte) {
  resultByte = 0; // by default, in case parsing fails

  unsigned char firstNibble;
  if (!getNibble(configStr, firstNibble)) return False;
  resultByte = firstNibble<<4;

  unsigned char secondNibble = 0;
  if (!getNibble(configStr, secondNibble) && configStr[0] != '\0') {
    // There's a second nibble, but it's malformed
    return False;
  }
  resultByte |= secondNibble;

  return True;
}

Boolean
parseStreamMuxConfigStr(char const* configStr,
                        // result parameters:
                        Boolean& audioMuxVersion,
                        Boolean& allStreamsSameTimeFraming,
                        unsigned char& numSubFrames,
                        unsigned char& numProgram,
                        unsigned char& numLayer,
                        unsigned char*& audioSpecificConfig,
                        unsigned& audioSpecificConfigSize) {
  // Set default versions of the result parameters:
  audioMuxVersion = False;
  allStreamsSameTimeFraming = True;
  numSubFrames = numProgram = numLayer = 0;
  audioSpecificConfig = NULL;
  audioSpecificConfigSize = 0;

  do {
    if (configStr == NULL) break;

    unsigned char nextByte;

    if (!getByte(configStr, nextByte)) break;
    audioMuxVersion = (nextByte&0x80) != 0;
    if (audioMuxVersion) break;

    allStreamsSameTimeFraming = ((nextByte&0x40)>>6) != 0;
    numSubFrames = (nextByte&0x3F);

    if (!getByte(configStr, nextByte)) break;
    numProgram = (nextByte&0xF0)>>4;

    numLayer = (nextByte&0x0E)>>1;

    // The one remaining bit, and the rest of the string,
    // are used for "audioSpecificConfig":
    unsigned char remainingBit = nextByte&1;

    unsigned ascSize = (strlen(configStr)+1)/2 + 1;
    audioSpecificConfig = new unsigned char[ascSize];

    Boolean parseSuccess;
    unsigned i = 0;
    do {
      nextByte = 0;
      parseSuccess = getByte(configStr, nextByte);
      audioSpecificConfig[i++] = (remainingBit<<7)|((nextByte&0xFE)>>1);
      remainingBit = nextByte&1;
    } while (parseSuccess);
    if (i != ascSize) break; // part of the remaining string was bad

    audioSpecificConfigSize = ascSize;
    return True; // parsing succeeded
  } while (0);

  delete[] audioSpecificConfig;
  return False; // parsing failed
}

unsigned char* parseStreamMuxConfigStr(char const* configStr,
				       // result parameter:
				       unsigned& audioSpecificConfigSize) {
  Boolean audioMuxVersion, allStreamsSameTimeFraming;
  unsigned char numSubFrames, numProgram, numLayer;
  unsigned char* audioSpecificConfig;

  if (!parseStreamMuxConfigStr(configStr,
			       audioMuxVersion, allStreamsSameTimeFraming,
			       numSubFrames, numProgram, numLayer,
			       audioSpecificConfig, audioSpecificConfigSize)) {
    audioSpecificConfigSize = 0;
    return NULL;
  }

  return audioSpecificConfig;
}

unsigned char* parseGeneralConfigStr(char const* configStr,
				     // result parameter:
				     unsigned& configSize) {
  unsigned char* config = NULL;
  do {
    if (configStr == NULL) break;
    configSize = (strlen(configStr)+1)/2;

    config = new unsigned char[configSize];
    if (config == NULL) break;

    unsigned i;
    for (i = 0; i < configSize; ++i) {
      if (!getByte(configStr, config[i])) break;
    }
    if (i != configSize) break; // part of the string was bad

    return config;
  } while (0);

  configSize = 0;
  delete[] config;
  return NULL;
}
