/**********
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 AMR audio (RFC 4867)
// Implementation

// NOTE: At present, this is just a limited implementation, supporting:
// octet-alignment only; no interleaving; no frame CRC; no robust-sorting.

#include "AMRAudioRTPSink.hh"
#include "AMRAudioSource.hh"

AMRAudioRTPSink*
AMRAudioRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
			   unsigned char rtpPayloadFormat,
			   Boolean sourceIsWideband,
			   unsigned numChannelsInSource) {
  return new AMRAudioRTPSink(env, RTPgs, rtpPayloadFormat,
			     sourceIsWideband, numChannelsInSource);
}

AMRAudioRTPSink
::AMRAudioRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
		  unsigned char rtpPayloadFormat,
		  Boolean sourceIsWideband, unsigned numChannelsInSource)
  : AudioRTPSink(env, RTPgs, rtpPayloadFormat,
		 sourceIsWideband ? 16000 : 8000,
		 sourceIsWideband ? "AMR-WB": "AMR",
		 numChannelsInSource),
  fSourceIsWideband(sourceIsWideband), fFmtpSDPLine(NULL) {
}

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

Boolean AMRAudioRTPSink::sourceIsCompatibleWithUs(MediaSource& source) {
  // Our source must be an AMR audio source:
  if (!source.isAMRAudioSource()) return False;

  // Also, the source must be wideband iff we asked for this:
  AMRAudioSource& amrSource = (AMRAudioSource&)source;
  if ((amrSource.isWideband()^fSourceIsWideband) != 0) return False;

  // Also, the source must have the same number of channels that we
  // specified.  (It could, in principle, have more, but we don't
  // support that.)
  if (amrSource.numChannels() != numChannels()) return False;

  // Also, because in our current implementation we output only one
  // frame in each RTP packet, this means that for multi-channel audio,
  // each 'frame-block' will be split over multiple RTP packets, which
  // may violate the spec.  Warn about this:
  if (amrSource.numChannels() > 1) {
    envir() << "AMRAudioRTPSink: Warning: Input source has " << amrSource.numChannels()
	    << " audio channels.  In the current implementation, the multi-frame frame-block will be split over multiple RTP packets\n";
  }

  return True;
}

void AMRAudioRTPSink::doSpecialFrameHandling(unsigned fragmentationOffset,
					     unsigned char* frameStart,
					     unsigned numBytesInFrame,
					     struct timeval framePresentationTime,
					     unsigned numRemainingBytes) {
  // If this is the 1st frame in the 1st packet, set the RTP 'M' (marker)
  // bit (because this is considered the start of a talk spurt):
  if (isFirstPacket() && isFirstFrameInPacket()) {
    setMarkerBit();
  }

  // If this is the first frame in the packet, set the 1-byte payload
  // header (using CMR 15)
  if (isFirstFrameInPacket()) {
    u_int8_t payloadHeader = 0xF0;
    setSpecialHeaderBytes(&payloadHeader, 1, 0);
  }

  // Set the TOC field for the current frame, based on the "FT" and "Q"
  // values from our source:
  AMRAudioSource* amrSource = (AMRAudioSource*)fSource;
  if (amrSource == NULL) return; // sanity check

  u_int8_t toc = amrSource->lastFrameHeader();
  // Clear the "F" bit, because we're the last frame in this packet: #####
  toc &=~ 0x80;
  setSpecialHeaderBytes(&toc, 1, 1+numFramesUsedSoFar());

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

Boolean AMRAudioRTPSink
::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
				 unsigned /*numBytesInFrame*/) const {
  // For now, pack only one AMR frame into each outgoing RTP packet: #####
  return False;
}

unsigned AMRAudioRTPSink::specialHeaderSize() const {
  // For now, because we're packing only one frame per packet,
  // there's just a 1-byte payload header, plus a 1-byte TOC #####
  return 2;
}

char const* AMRAudioRTPSink::auxSDPLine() {
  if (fFmtpSDPLine == NULL) {
    // Generate a "a=fmtp:" line with "octet-aligned=1"
    // (That is the only non-default parameter.)
    char buf[100];
    sprintf(buf, "a=fmtp:%d octet-align=1\r\n", rtpPayloadType());
    delete[] fFmtpSDPLine; fFmtpSDPLine = strDup(buf);
  }
  return fFmtpSDPLine;
}
