/**********
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 2.1 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-2015 Live Networks, Inc.  All rights reserved.
// RTP Sinks
// Implementation

#include "RTPSink.hh"
#include "GroupsockHelper.hh"

////////// RTPSink //////////

Boolean RTPSink::lookupByName(UsageEnvironment& env, char const* sinkName,
				RTPSink*& resultSink) {
  resultSink = NULL; // unless we succeed

  MediaSink* sink;
  if (!MediaSink::lookupByName(env, sinkName, sink)) return False;

  if (!sink->isRTPSink()) {
    env.setResultMsg(sinkName, " is not a RTP sink");
    return False;
  }

  resultSink = (RTPSink*)sink;
  return True;
}

Boolean RTPSink::isRTPSink() const {
  return True;
}

RTPSink::RTPSink(UsageEnvironment& env,
		 Groupsock* rtpGS, unsigned char rtpPayloadType,
		 unsigned rtpTimestampFrequency,
		 char const* rtpPayloadFormatName,
		 unsigned numChannels)
  : MediaSink(env), fRTPInterface(this, rtpGS),
    fRTPPayloadType(rtpPayloadType),
    fPacketCount(0), fOctetCount(0), fTotalOctetCount(0),
    fTimestampFrequency(rtpTimestampFrequency), fNextTimestampHasBeenPreset(False), fEnableRTCPReports(True),
    fNumChannels(numChannels), fEstimatedBitrate(0) {
  fRTPPayloadFormatName
    = strDup(rtpPayloadFormatName == NULL ? "???" : rtpPayloadFormatName);
  gettimeofday(&fCreationTime, NULL);
  fTotalOctetCountStartTime = fCreationTime;
  resetPresentationTimes();

  fSeqNo = (u_int16_t)our_random();
  fSSRC = our_random32();
  fTimestampBase = our_random32();

  fTransmissionStatsDB = new RTPTransmissionStatsDB(*this);
}

RTPSink::~RTPSink() {
  delete fTransmissionStatsDB;
  delete[] (char*)fRTPPayloadFormatName;
  fRTPInterface.forgetOurGroupsock();
    // so that the "fRTCPInterface" destructor doesn't turn off background read handling (in case
    // its 'groupsock' is being shared with something else that does background read handling).
}

u_int32_t RTPSink::convertToRTPTimestamp(struct timeval tv) {
  // Begin by converting from "struct timeval" units to RTP timestamp units:
  u_int32_t timestampIncrement = (fTimestampFrequency*tv.tv_sec);
  timestampIncrement += (u_int32_t)(fTimestampFrequency*(tv.tv_usec/1000000.0) + 0.5); // note: rounding

  // Then add this to our 'timestamp base':
  if (fNextTimestampHasBeenPreset) {
    // Make the returned timestamp the same as the current "fTimestampBase",
    // so that timestamps begin with the value that was previously preset:
    fTimestampBase -= timestampIncrement;
    fNextTimestampHasBeenPreset = False;
  }

  u_int32_t const rtpTimestamp = fTimestampBase + timestampIncrement;
#ifdef DEBUG_TIMESTAMPS
  fprintf(stderr, "fTimestampBase: 0x%08x, tv: %lu.%06ld\n\t=> RTP timestamp: 0x%08x\n",
	  fTimestampBase, tv.tv_sec, tv.tv_usec, rtpTimestamp);
  fflush(stderr);
#endif

  return rtpTimestamp;
}

u_int32_t RTPSink::presetNextTimestamp() {
  struct timeval timeNow;
  gettimeofday(&timeNow, NULL);

  u_int32_t tsNow = convertToRTPTimestamp(timeNow);
  fTimestampBase = tsNow;
  fNextTimestampHasBeenPreset = True;

  return tsNow;
}

void RTPSink::getTotalBitrate(unsigned& outNumBytes, double& outElapsedTime) {
  struct timeval timeNow;
  gettimeofday(&timeNow, NULL);

  outNumBytes = fTotalOctetCount;
  outElapsedTime = (double)(timeNow.tv_sec-fTotalOctetCountStartTime.tv_sec)
    + (timeNow.tv_usec-fTotalOctetCountStartTime.tv_usec)/1000000.0;

  fTotalOctetCount = 0;
  fTotalOctetCountStartTime = timeNow;
}

void RTPSink::resetPresentationTimes() {
  fInitialPresentationTime.tv_sec = fMostRecentPresentationTime.tv_sec = 0;
  fInitialPresentationTime.tv_usec = fMostRecentPresentationTime.tv_usec = 0;
}

char const* RTPSink::sdpMediaType() const {
  return "data";
  // default SDP media (m=) type, unless redefined by subclasses
}

char* RTPSink::rtpmapLine() const {
  if (rtpPayloadType() >= 96) { // the payload format type is dynamic
    char* encodingParamsPart;
    if (numChannels() != 1) {
      encodingParamsPart = new char[1 + 20 /* max int len */];
      sprintf(encodingParamsPart, "/%d", numChannels());
    } else {
      encodingParamsPart = strDup("");
    }
    char const* const rtpmapFmt = "a=rtpmap:%d %s/%d%s\r\n";
    unsigned rtpmapFmtSize = strlen(rtpmapFmt)
      + 3 /* max char len */ + strlen(rtpPayloadFormatName())
      + 20 /* max int len */ + strlen(encodingParamsPart);
    char* rtpmapLine = new char[rtpmapFmtSize];
    sprintf(rtpmapLine, rtpmapFmt,
	    rtpPayloadType(), rtpPayloadFormatName(),
	    rtpTimestampFrequency(), encodingParamsPart);
    delete[] encodingParamsPart;

    return rtpmapLine;
  } else {
    // The payload format is staic, so there's no "a=rtpmap:" line:
    return strDup("");
  }
}

char const* RTPSink::auxSDPLine() {
  return NULL; // by default
}


////////// RTPTransmissionStatsDB //////////

RTPTransmissionStatsDB::RTPTransmissionStatsDB(RTPSink& rtpSink)
  : fOurRTPSink(rtpSink),
    fTable(HashTable::create(ONE_WORD_HASH_KEYS)) {
  fNumReceivers=0;
}

RTPTransmissionStatsDB::~RTPTransmissionStatsDB() {
  // First, remove and delete all stats records from the table:
  RTPTransmissionStats* stats;
  while ((stats = (RTPTransmissionStats*)fTable->RemoveNext()) != NULL) {
    delete stats;
  }

  // Then, delete the table itself:
  delete fTable;
}

void RTPTransmissionStatsDB
::noteIncomingRR(u_int32_t SSRC, struct sockaddr_in const& lastFromAddress,
                 unsigned lossStats, unsigned lastPacketNumReceived,
                 unsigned jitter, unsigned lastSRTime, unsigned diffSR_RRTime) {
  RTPTransmissionStats* stats = lookup(SSRC);
  if (stats == NULL) {
    // This is the first time we've heard of this SSRC.
    // Create a new record for it:
    stats = new RTPTransmissionStats(fOurRTPSink, SSRC);
    if (stats == NULL) return;
    add(SSRC, stats);
#ifdef DEBUG_RR
    fprintf(stderr, "Adding new entry for SSRC %x in RTPTransmissionStatsDB\n", SSRC);
#endif
  }

  stats->noteIncomingRR(lastFromAddress,
			lossStats, lastPacketNumReceived, jitter,
                        lastSRTime, diffSR_RRTime);
}

void RTPTransmissionStatsDB::removeRecord(u_int32_t SSRC) {
  RTPTransmissionStats* stats = lookup(SSRC);
  if (stats != NULL) {
    long SSRC_long = (long)SSRC;
    fTable->Remove((char const*)SSRC_long);
    --fNumReceivers;
    delete stats;
  }
}

RTPTransmissionStatsDB::Iterator
::Iterator(RTPTransmissionStatsDB& receptionStatsDB)
  : fIter(HashTable::Iterator::create(*(receptionStatsDB.fTable))) {
}

RTPTransmissionStatsDB::Iterator::~Iterator() {
  delete fIter;
}

RTPTransmissionStats*
RTPTransmissionStatsDB::Iterator::next() {
  char const* key; // dummy

  return (RTPTransmissionStats*)(fIter->next(key));
}

RTPTransmissionStats* RTPTransmissionStatsDB::lookup(u_int32_t SSRC) const {
  long SSRC_long = (long)SSRC;
  return (RTPTransmissionStats*)(fTable->Lookup((char const*)SSRC_long));
}

void RTPTransmissionStatsDB::add(u_int32_t SSRC, RTPTransmissionStats* stats) {
  long SSRC_long = (long)SSRC;
  fTable->Add((char const*)SSRC_long, stats);
  ++fNumReceivers;
}


////////// RTPTransmissionStats //////////

RTPTransmissionStats::RTPTransmissionStats(RTPSink& rtpSink, u_int32_t SSRC)
  : fOurRTPSink(rtpSink), fSSRC(SSRC), fLastPacketNumReceived(0),
    fPacketLossRatio(0), fTotNumPacketsLost(0), fJitter(0),
    fLastSRTime(0), fDiffSR_RRTime(0), fAtLeastTwoRRsHaveBeenReceived(False), fFirstPacket(True),
    fTotalOctetCount_hi(0), fTotalOctetCount_lo(0),
    fTotalPacketCount_hi(0), fTotalPacketCount_lo(0) {
  gettimeofday(&fTimeCreated, NULL);

  fLastOctetCount = rtpSink.octetCount();
  fLastPacketCount = rtpSink.packetCount();
}

RTPTransmissionStats::~RTPTransmissionStats() {}

void RTPTransmissionStats
::noteIncomingRR(struct sockaddr_in const& lastFromAddress,
		 unsigned lossStats, unsigned lastPacketNumReceived,
		 unsigned jitter, unsigned lastSRTime,
		 unsigned diffSR_RRTime) {
  if (fFirstPacket) {
    fFirstPacket = False;
    fFirstPacketNumReported = lastPacketNumReceived;
  } else {
    fAtLeastTwoRRsHaveBeenReceived = True;
    fOldLastPacketNumReceived = fLastPacketNumReceived;
    fOldTotNumPacketsLost = fTotNumPacketsLost;
  }
  gettimeofday(&fTimeReceived, NULL);

  fLastFromAddress = lastFromAddress;
  fPacketLossRatio = lossStats>>24;
  fTotNumPacketsLost = lossStats&0xFFFFFF;
  fLastPacketNumReceived = lastPacketNumReceived;
  fJitter = jitter;
  fLastSRTime = lastSRTime;
  fDiffSR_RRTime = diffSR_RRTime;
#ifdef DEBUG_RR
  fprintf(stderr, "RTCP RR data (received at %lu.%06ld): lossStats 0x%08x, lastPacketNumReceived 0x%08x, jitter 0x%08x, lastSRTime 0x%08x, diffSR_RRTime 0x%08x\n",
          fTimeReceived.tv_sec, fTimeReceived.tv_usec, lossStats, lastPacketNumReceived, jitter, lastSRTime, diffSR_RRTime);
  unsigned rtd = roundTripDelay();
  fprintf(stderr, "=> round-trip delay: 0x%04x (== %f seconds)\n", rtd, rtd/65536.0);
#endif

  // Update our counts of the total number of octets and packets sent towards
  // this receiver:
  u_int32_t newOctetCount = fOurRTPSink.octetCount();
  u_int32_t octetCountDiff = newOctetCount - fLastOctetCount;
  fLastOctetCount = newOctetCount;
  u_int32_t prevTotalOctetCount_lo = fTotalOctetCount_lo;
  fTotalOctetCount_lo += octetCountDiff;
  if (fTotalOctetCount_lo < prevTotalOctetCount_lo) { // wrap around
    ++fTotalOctetCount_hi;
  }

  u_int32_t newPacketCount = fOurRTPSink.packetCount();
  u_int32_t packetCountDiff = newPacketCount - fLastPacketCount;
  fLastPacketCount = newPacketCount;
  u_int32_t prevTotalPacketCount_lo = fTotalPacketCount_lo;
  fTotalPacketCount_lo += packetCountDiff;
  if (fTotalPacketCount_lo < prevTotalPacketCount_lo) { // wrap around
    ++fTotalPacketCount_hi;
  }
}

unsigned RTPTransmissionStats::roundTripDelay() const {
  // Compute the round-trip delay that was indicated by the most recently-received
  // RTCP RR packet.  Use the method noted in the RTP/RTCP specification (RFC 3350).

  if (fLastSRTime == 0) {
    // Either no RTCP RR packet has been received yet, or else the
    // reporting receiver has not yet received any RTCP SR packets from us:
    return 0;
  }

  // First, convert the time that we received the last RTCP RR packet to NTP format,
  // in units of 1/65536 (2^-16) seconds:
  unsigned lastReceivedTimeNTP_high
    = fTimeReceived.tv_sec + 0x83AA7E80; // 1970 epoch -> 1900 epoch
  double fractionalPart = (fTimeReceived.tv_usec*0x0400)/15625.0; // 2^16/10^6
  unsigned lastReceivedTimeNTP
    = (unsigned)((lastReceivedTimeNTP_high<<16) + fractionalPart + 0.5);

  int rawResult = lastReceivedTimeNTP - fLastSRTime - fDiffSR_RRTime;
  if (rawResult < 0) {
    // This can happen if there's clock drift between the sender and receiver,
    // and if the round-trip time was very small.
    rawResult = 0;
  }
  return (unsigned)rawResult;
}

void RTPTransmissionStats::getTotalOctetCount(u_int32_t& hi, u_int32_t& lo) {
  hi = fTotalOctetCount_hi;
  lo = fTotalOctetCount_lo;
}

void RTPTransmissionStats::getTotalPacketCount(u_int32_t& hi, u_int32_t& lo) {
  hi = fTotalPacketCount_hi;
  lo = fTotalPacketCount_lo;
}

unsigned RTPTransmissionStats::packetsReceivedSinceLastRR() const {
  if (!fAtLeastTwoRRsHaveBeenReceived) return 0;

  return fLastPacketNumReceived-fOldLastPacketNumReceived;
}

int RTPTransmissionStats::packetsLostBetweenRR() const {
  if (!fAtLeastTwoRRsHaveBeenReceived) return 0;

  return fTotNumPacketsLost - fOldTotNumPacketsLost;
}
