/**********
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.
// Vorbis Audio RTP Sources
// Implementation

#include "VorbisAudioRTPSource.hh"
#include "Base64.hh"

////////// VorbisBufferedPacket and VorbisBufferedPacketFactory //////////

class VorbisBufferedPacket: public BufferedPacket {
public:
  VorbisBufferedPacket();
  virtual ~VorbisBufferedPacket();

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

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


///////// VorbisAudioRTPSource implementation ////////

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

VorbisAudioRTPSource
::VorbisAudioRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
		     unsigned char rtpPayloadFormat,
		     unsigned rtpTimestampFrequency)
  : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency,
			 new VorbisBufferedPacketFactory),
    fCurPacketIdent(0) {
}

VorbisAudioRTPSource::~VorbisAudioRTPSource() {
}

Boolean VorbisAudioRTPSource
::processSpecialHeader(BufferedPacket* packet,
                       unsigned& resultSpecialHeaderSize) {
  unsigned char* headerStart = packet->data();
  unsigned packetSize = packet->dataSize();

  resultSpecialHeaderSize = 4;
  if (packetSize < resultSpecialHeaderSize) return False; // packet was too small

  // The first 3 bytes of the header are the "Ident" field:
  fCurPacketIdent = (headerStart[0]<<16) | (headerStart[1]<<8) | headerStart[2];

  // The 4th byte is F|VDT|numPkts.
  // Reject any packet with VDT == 3:
  if ((headerStart[3]&0x30) == 0x30) return False;

  u_int8_t F = headerStart[3]>>6;
  fCurrentPacketBeginsFrame = F <= 1; // "Not Fragmented" or "Start Fragment"
  fCurrentPacketCompletesFrame = F == 0 || F == 3; // "Not Fragmented" or "End Fragment"

  return True;
}

char const* VorbisAudioRTPSource::MIMEtype() const {
  return "audio/VORBIS";
}


////////// VorbisBufferedPacket and VorbisBufferedPacketFactory implementation //////////

VorbisBufferedPacket::VorbisBufferedPacket() {
}

VorbisBufferedPacket::~VorbisBufferedPacket() {
}

unsigned VorbisBufferedPacket
::nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {
  if (dataSize < 2) {
    // There's not enough space for a 2-byte header.  TARFU!  Just return the data that's left:
    return dataSize;
  }

  unsigned frameSize = (framePtr[0]<<8) | framePtr[1];
  framePtr += 2;
  if (frameSize > dataSize - 2) return dataSize - 2; // inconsistent frame size => just return all the data that's left

  return frameSize;
}

BufferedPacket* VorbisBufferedPacketFactory
::createNewPacket(MultiFramedRTPSource* /*ourSource*/) {
  return new VorbisBufferedPacket();
}


////////// parseVorbisOrTheoraConfigStr() implementation //////////

#define ADVANCE(n) do { p += (n); rem -= (n); } while (0)
#define GET_ENCODED_VAL(n) do { u_int8_t byte; n = 0; do { if (rem == 0) break; byte = *p; n = (n*128) + (byte&0x7F); ADVANCE(1); } while (byte&0x80); } while (0); if (rem == 0) break

void parseVorbisOrTheoraConfigStr(char const* configStr,
                                  u_int8_t*& identificationHdr, unsigned& identificationHdrSize,
                                  u_int8_t*& commentHdr, unsigned& commentHdrSize,
                                  u_int8_t*& setupHdr, unsigned& setupHdrSize,
				  u_int32_t& identField) {
  identificationHdr = commentHdr = setupHdr = NULL; // default values, if an error occur
  identificationHdrSize = commentHdrSize = setupHdrSize = 0; // ditto
  identField = 0; // ditto

  // Begin by Base64-decoding the configuration string:
  unsigned configDataSize;
  u_int8_t* configData = base64Decode(configStr, configDataSize);
  u_int8_t* p = configData;
  unsigned rem = configDataSize;

  do {
    if (rem < 4) break;
    u_int32_t numPackedHeaders = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; ADVANCE(4);
    if (numPackedHeaders == 0) break;

    // Use the first 'packed header' only.
    if (rem < 3) break;
    identField = (p[0]<<16)|(p[1]<<8)|p[2]; ADVANCE(3);

    if (rem < 2) break;
    u_int16_t length = (p[0]<<8)|p[1]; ADVANCE(2);

    unsigned numHeaders;
    GET_ENCODED_VAL(numHeaders);

    Boolean success = False;
    for (unsigned i = 0; i < numHeaders+1 && i < 3; ++i) {
      success = False;
      unsigned headerSize;
      if (i < numHeaders) {
        // The header size is encoded:
	GET_ENCODED_VAL(headerSize);
        if (headerSize > length) break;
        length -= headerSize;
      } else {
	// The last header is implicit:
        headerSize = length;
      }

      // Allocate space for the header bytes; we'll fill it in later
      if (i == 0) {
	identificationHdrSize = headerSize;
        identificationHdr = new u_int8_t[identificationHdrSize];
      } else if (i == 1) {
        commentHdrSize = headerSize;
	commentHdr = new u_int8_t[commentHdrSize];
      } else { // i == 2
        setupHdrSize = headerSize;
        setupHdr = new u_int8_t[setupHdrSize];
      }

      success = True;
    }
    if (!success) break;

    // Copy the remaining config bytes into the appropriate 'header' buffers:
    if (identificationHdr != NULL) {
      memmove(identificationHdr, p, identificationHdrSize); ADVANCE(identificationHdrSize);
      if (commentHdr != NULL) {
        memmove(commentHdr, p, commentHdrSize); ADVANCE(commentHdrSize);
	if (setupHdr != NULL) {
          memmove(setupHdr, p, setupHdrSize); ADVANCE(setupHdrSize);
        }
      }
    }
  } while (0);

  delete[] configData;
}
