/**********
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 T.140 text (RFC 2793)
// Implementation

#include "T140TextRTPSink.hh"
#include <GroupsockHelper.hh> // for "gettimeofday()"

////////// T140TextRTPSink implementation //////////

T140TextRTPSink::T140TextRTPSink(UsageEnvironment& env, Groupsock* RTPgs, unsigned char rtpPayloadFormat)
  : TextRTPSink(env, RTPgs, rtpPayloadFormat, 1000/*mandatory RTP timestamp frequency for this payload format*/, "T140"),
    fOurIdleFilter(NULL), fAreInIdlePeriod(True) {
}

T140TextRTPSink::~T140TextRTPSink() {
  fSource = fOurIdleFilter; // hack: in case "fSource" had gotten set to NULL before we were called
  stopPlaying(); // call this now, because we won't have our 'idle filter' when the base class destructor calls it later.

  // Close our 'idle filter' as well:
  Medium::close(fOurIdleFilter);
  fSource = NULL; // for the base class destructor, which gets called next
}

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

Boolean T140TextRTPSink::continuePlaying() {
  // First, check whether we have an 'idle filter' set up yet. If not, create it now, and insert it in front of our existing source:
  if (fOurIdleFilter == NULL) {
    fOurIdleFilter = new T140IdleFilter(envir(), fSource);
  } else {
    fOurIdleFilter->reassignInputSource(fSource);
  }
  fSource = fOurIdleFilter;

  // Then call the parent class's implementation:
  return MultiFramedRTPSink::continuePlaying();
}

void T140TextRTPSink::doSpecialFrameHandling(unsigned /*fragmentationOffset*/,
					     unsigned char* /*frameStart*/,
					     unsigned numBytesInFrame,
					     struct timeval framePresentationTime,
					     unsigned /*numRemainingBytes*/) {
  // Set the RTP 'M' (marker) bit if we have just ended an idle period - i.e., if we were in an idle period, but just got data:
  if (fAreInIdlePeriod && numBytesInFrame > 0) setMarkerBit();
  fAreInIdlePeriod = numBytesInFrame == 0;

  setTimestamp(framePresentationTime);
}

Boolean T140TextRTPSink::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/, unsigned /*numBytesInFrame*/) const {
  return False; // We don't concatenate input data; instead, send it out immediately
}


////////// T140IdleFilter implementation //////////

T140IdleFilter::T140IdleFilter(UsageEnvironment& env, FramedSource* inputSource)
  : FramedFilter(env, inputSource),
    fIdleTimerTask(NULL),
    fBufferSize(OutPacketBuffer::maxSize), fNumBufferedBytes(0) {
  fBuffer = new char[fBufferSize];
}

T140IdleFilter::~T140IdleFilter() {
  envir().taskScheduler().unscheduleDelayedTask(fIdleTimerTask);

  delete[] fBuffer;
  detachInputSource(); // so that the subsequent ~FramedFilter() doesn't delete it
}

#define IDLE_TIMEOUT_MICROSECONDS 300000 /* 300 ms */

void T140IdleFilter::doGetNextFrame() {
  // First, see if we have buffered data that we can deliver:
  if (fNumBufferedBytes > 0) {
    deliverFromBuffer();
    return;
  }

  // We don't have any buffered data, so ask our input source for data (unless we've already done so).
  // But also set a timer to expire if this doesn't arrive promptly:
  fIdleTimerTask = envir().taskScheduler().scheduleDelayedTask(IDLE_TIMEOUT_MICROSECONDS, handleIdleTimeout, this);
  if (fInputSource != NULL && !fInputSource->isCurrentlyAwaitingData()) {
    fInputSource->getNextFrame((unsigned char*)fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);
  }
}

void T140IdleFilter::afterGettingFrame(void* clientData, unsigned frameSize,
				       unsigned numTruncatedBytes,
				       struct timeval presentationTime,
				       unsigned durationInMicroseconds) {
  ((T140IdleFilter*)clientData)->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
}

void T140IdleFilter::afterGettingFrame(unsigned frameSize,
				       unsigned numTruncatedBytes,
				       struct timeval presentationTime,
				       unsigned durationInMicroseconds) {
  // First, cancel any pending idle timer:
  envir().taskScheduler().unscheduleDelayedTask(fIdleTimerTask);

  // Then note the new data that we have in our buffer:
  fNumBufferedBytes = frameSize;
  fBufferedNumTruncatedBytes = numTruncatedBytes;
  fBufferedDataPresentationTime = presentationTime;
  fBufferedDataDurationInMicroseconds = durationInMicroseconds;

  // Then, attempt to deliver this data.  (If we can't deliver it now, we'll do so the next time the reader asks for data.)
  if (isCurrentlyAwaitingData()) (void)deliverFromBuffer();
}

void T140IdleFilter::doStopGettingFrames() {
  // Cancel any pending idle timer:
  envir().taskScheduler().unscheduleDelayedTask(fIdleTimerTask);

  // And call the parent's implementation of this virtual function:
  FramedFilter::doStopGettingFrames();
}

void T140IdleFilter::handleIdleTimeout(void* clientData) {
  ((T140IdleFilter*)clientData)->handleIdleTimeout();
}

void T140IdleFilter::handleIdleTimeout() {
  fIdleTimerTask = NULL;
  // No data has arrived from the upstream source within our specified 'idle period' (after data was requested from downstream).
  // Send an empty 'idle' frame to our downstream "T140TextRTPSink".  (This will cause an empty RTP packet to get sent.)
  deliverEmptyFrame();
}

void T140IdleFilter::deliverFromBuffer() {
  if (fNumBufferedBytes <= fMaxSize) { // common case
    fNumTruncatedBytes = fBufferedNumTruncatedBytes;
    fFrameSize = fNumBufferedBytes;
  } else {
    fNumTruncatedBytes = fBufferedNumTruncatedBytes + fNumBufferedBytes - fMaxSize;
    fFrameSize = fMaxSize;
  }  

  memmove(fTo, fBuffer, fFrameSize);
  fPresentationTime = fBufferedDataPresentationTime;
  fDurationInMicroseconds = fBufferedDataDurationInMicroseconds;

  fNumBufferedBytes = 0; // reset buffer
  
  FramedSource::afterGetting(this); // complete delivery
}

void T140IdleFilter::deliverEmptyFrame() {
  fFrameSize = fNumTruncatedBytes = 0;
  gettimeofday(&fPresentationTime, NULL);
  FramedSource::afterGetting(this); // complete delivery
}

void T140IdleFilter::onSourceClosure(void* clientData) {
  ((T140IdleFilter*)clientData)->onSourceClosure();
}

void T140IdleFilter::onSourceClosure() {
  envir().taskScheduler().unscheduleDelayedTask(fIdleTimerTask);

  handleClosure();
}
