/**********
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.
// RTP sink for Vorbis audio
// Implementation

#include "VorbisAudioRTPSink.hh"
#include "Base64.hh"
#include "VorbisAudioRTPSource.hh" // for parseVorbisOrTheoraConfigStr()

VorbisAudioRTPSink* VorbisAudioRTPSink
::createNew(UsageEnvironment& env, Groupsock* RTPgs,
	    u_int8_t rtpPayloadFormat, u_int32_t rtpTimestampFrequency, unsigned numChannels,
	    u_int8_t* identificationHeader, unsigned identificationHeaderSize,
	    u_int8_t* commentHeader, unsigned commentHeaderSize,
	    u_int8_t* setupHeader, unsigned setupHeaderSize,
	    u_int32_t identField) {
  return new VorbisAudioRTPSink(env, RTPgs,
				rtpPayloadFormat, rtpTimestampFrequency, numChannels,
				identificationHeader, identificationHeaderSize,
				commentHeader, commentHeaderSize,
				setupHeader, setupHeaderSize,
				identField);
}

VorbisAudioRTPSink* VorbisAudioRTPSink
::createNew(UsageEnvironment& env, Groupsock* RTPgs,u_int8_t rtpPayloadFormat,
	    u_int32_t rtpTimestampFrequency, unsigned numChannels,
	    char const* configStr) {
  // Begin by decoding and unpacking the configuration string:
  u_int8_t* identificationHeader; unsigned identificationHeaderSize;
  u_int8_t* commentHeader; unsigned commentHeaderSize;
  u_int8_t* setupHeader; unsigned setupHeaderSize;
  u_int32_t identField;

  parseVorbisOrTheoraConfigStr(configStr,
			       identificationHeader, identificationHeaderSize,
			       commentHeader, commentHeaderSize,
			       setupHeader, setupHeaderSize,
			       identField);

  VorbisAudioRTPSink* resultSink
    = new VorbisAudioRTPSink(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency, numChannels,
			     identificationHeader, identificationHeaderSize,
			     commentHeader, commentHeaderSize,
			     setupHeader, setupHeaderSize,
			     identField);
  delete[] identificationHeader; delete[] commentHeader; delete[] setupHeader;

  return resultSink;
}

VorbisAudioRTPSink
::VorbisAudioRTPSink(UsageEnvironment& env, Groupsock* RTPgs, u_int8_t rtpPayloadFormat,
		     u_int32_t rtpTimestampFrequency, unsigned numChannels,
		     u_int8_t* identificationHeader, unsigned identificationHeaderSize,
		     u_int8_t* commentHeader, unsigned commentHeaderSize,
		     u_int8_t* setupHeader, unsigned setupHeaderSize,
		     u_int32_t identField)
  : AudioRTPSink(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency, "VORBIS", numChannels),
    fIdent(identField), fFmtpSDPLine(NULL) {
  if (identificationHeaderSize >= 28) {
    // Get the 'bitrate' values from this header, and use them to set our estimated bitrate:
    u_int32_t val;
    u_int8_t* p;
    
    p = &identificationHeader[16];
    val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0]; // i.e., little-endian
    int bitrate_maximum = (int)val;
    if (bitrate_maximum < 0) bitrate_maximum = 0;
    
    p = &identificationHeader[20];
    val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0]; // i.e., little-endian
    int bitrate_nominal = (int)val;
    if (bitrate_nominal < 0) bitrate_nominal = 0;
    
    p = &identificationHeader[24];
    val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0]; // i.e., little-endian
    int bitrate_minimum = (int)val;
    if (bitrate_minimum < 0) bitrate_minimum = 0;
    
    int bitrate
      = bitrate_nominal > 0 ? bitrate_nominal
      : bitrate_maximum > 0 ? bitrate_maximum
      : bitrate_minimum > 0 ? bitrate_minimum : 0;
    if (bitrate > 0) estimatedBitrate() = ((unsigned)bitrate)/1000;
  }
  
  // Generate a 'config' string from the supplied configuration headers:
  char* base64PackedHeaders
    = generateVorbisOrTheoraConfigStr(identificationHeader, identificationHeaderSize,
				      commentHeader, commentHeaderSize,
				      setupHeader, setupHeaderSize,
				      identField);
  if (base64PackedHeaders == NULL) return;
  
  // Then use this 'config' string to construct our "a=fmtp:" SDP line:
  unsigned fmtpSDPLineMaxSize = 50 + strlen(base64PackedHeaders); // 50 => more than enough space
  fFmtpSDPLine = new char[fmtpSDPLineMaxSize];
  sprintf(fFmtpSDPLine, "a=fmtp:%d configuration=%s\r\n", rtpPayloadType(), base64PackedHeaders);
  delete[] base64PackedHeaders;
}

VorbisAudioRTPSink::~VorbisAudioRTPSink() {
  delete[] fFmtpSDPLine;
}

char const* VorbisAudioRTPSink::auxSDPLine() {
  return fFmtpSDPLine;
}

void VorbisAudioRTPSink
::doSpecialFrameHandling(unsigned fragmentationOffset,
			 unsigned char* frameStart,
			 unsigned numBytesInFrame,
			 struct timeval framePresentationTime,
			 unsigned numRemainingBytes) {
  // Set the 4-byte "payload header", as defined in RFC 5215, section 2.2:
  u_int8_t header[4];

  // The first three bytes of the header are our "Ident":
  header[0] = fIdent>>16; header[1] = fIdent>>8; header[2] = fIdent;

  // The final byte contains the "F", "VDT", and "numPkts" fields:
  u_int8_t F; // Fragment type
  if (numRemainingBytes > 0) {
    if (fragmentationOffset > 0) {
      F = 2<<6; // continuation fragment
    } else {
      F = 1<<6; // start fragment
    }
  } else {
    if (fragmentationOffset > 0) {
      F = 3<<6; // end fragment
    } else {
      F = 0<<6; // not fragmented
    }
  }
  u_int8_t const VDT = 0<<4; // Vorbis Data Type (always a "Raw Vorbis payload")
  u_int8_t numPkts = F == 0 ? (numFramesUsedSoFar() + 1): 0; // set to 0 when we're a fragment
  header[3] = F|VDT|numPkts;

  setSpecialHeaderBytes(header, sizeof header);

  // There's also a 2-byte 'frame-specific' header: The length of the Vorbis data:
  u_int8_t frameSpecificHeader[2];
  frameSpecificHeader[0] = numBytesInFrame>>8;
  frameSpecificHeader[1] = numBytesInFrame;
  setFrameSpecificHeaderBytes(frameSpecificHeader, 2);

  // Important: Also call our base class's doSpecialFrameHandling(),
  // to set the packet's timestamp:
  MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
					     frameStart, numBytesInFrame,
					     framePresentationTime,
					     numRemainingBytes);
}

Boolean VorbisAudioRTPSink::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
							   unsigned /*numBytesInFrame*/) const {
  // We allow more than one frame to be packed into an outgoing RTP packet, but no more than 15:
  return numFramesUsedSoFar() <= 15;
}

unsigned VorbisAudioRTPSink::specialHeaderSize() const {
  return 4;
}

unsigned VorbisAudioRTPSink::frameSpecificHeaderSize() const {
  return 2;
}


////////// generateVorbisOrTheoraConfigStr() implementation //////////

char* generateVorbisOrTheoraConfigStr(u_int8_t* identificationHeader, unsigned identificationHeaderSize,
                                      u_int8_t* commentHeader, unsigned commentHeaderSize,
                                      u_int8_t* setupHeader, unsigned setupHeaderSize,
                                      u_int32_t identField) {
  // First, count how many headers (<=3) are included, and how many bytes will be used
  // to encode these headers' sizes:
  unsigned numHeaders = 0;
  unsigned sizeSize[2]; // The number of bytes used to encode the lengths of the first two headers (but not the length of the 3rd)
  sizeSize[0] = sizeSize[1] = 0;
  if (identificationHeaderSize > 0) {
    sizeSize[numHeaders++] = identificationHeaderSize < 128 ? 1 : identificationHeaderSize < 16384 ? 2 : 3;
  }
  if (commentHeaderSize > 0) {
    sizeSize[numHeaders++] = commentHeaderSize < 128 ? 1 : commentHeaderSize < 16384 ? 2 : 3;
  }
  if (setupHeaderSize > 0) {
    ++numHeaders;
  } else {
    sizeSize[1] = 0; // We have at most two headers, so the second one's length isn't encoded
  }
  if (numHeaders == 0) return NULL; // With no headers, we can't set up a configuration
  if (numHeaders == 1) sizeSize[0] = 0; // With only one header, its length isn't encoded

  // Then figure out the size of the packed configuration headers, and allocate space for this:
  unsigned length = identificationHeaderSize + commentHeaderSize + setupHeaderSize;
      // The "length" field in the packed headers
  if (length > (unsigned)0xFFFF) return NULL; // too big for a 16-bit field; we can't handle this
  unsigned packedHeadersSize
    = 4 // "Number of packed headers" field
    + 3 // "ident" field
    + 2 // "length" field
    + 1 // "n. of headers" field
    + sizeSize[0] + sizeSize[1] // "length1" and "length2" (if present) fields
    + length;
  u_int8_t* packedHeaders = new u_int8_t[packedHeadersSize];
  if (packedHeaders == NULL) return NULL;

  // Fill in the 'packed headers':
  u_int8_t* p = packedHeaders;
  *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 1; // "Number of packed headers": 1
  *p++ = identField>>16; *p++ = identField>>8; *p++ = identField; // "Ident" (24 bits)
  *p++ = length>>8; *p++ = length; // "length" (16 bits)
  *p++ = numHeaders-1; // "n. of headers"
  if (numHeaders > 1) {
    // Fill in the "length1" header:
    unsigned length1 = identificationHeaderSize > 0 ? identificationHeaderSize : commentHeaderSize;
    if (length1 >= 16384) {
      *p++ = 0x80; // flag, but no more, because we know length1 <= 32767
    }
    if (length1 >= 128) {
      *p++ = 0x80|((length1&0x3F80)>>7); // flag + the second 7 bits
    }
    *p++ = length1&0x7F; // the low 7 bits

    if (numHeaders > 2) { // numHeaders == 3
      // Fill in the "length2" header (for the 'Comment' header):
      unsigned length2 = commentHeaderSize;
      if (length2 >= 16384) {
	*p++ = 0x80; // flag, but no more, because we know length2 <= 32767
      }
      if (length2 >= 128) {
	*p++ = 0x80|((length2&0x3F80)>>7); // flag + the second 7 bits
      }
      *p++ = length2&0x7F; // the low 7 bits
    }
  }
  // Copy each header:
  if (identificationHeader != NULL) memmove(p, identificationHeader, identificationHeaderSize); p += identificationHeaderSize;
  if (commentHeader != NULL) memmove(p, commentHeader, commentHeaderSize); p += commentHeaderSize;
  if (setupHeader != NULL) memmove(p, setupHeader, setupHeaderSize);
  
  // Having set up the 'packed configuration headers', Base-64-encode this, for our result:
  char* base64PackedHeaders = base64Encode((char const*)packedHeaders, packedHeadersSize);
  delete[] packedHeaders;
  
  return base64PackedHeaders;
}
