/**********
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
**********/
// Copyright (c) 1996-2020, Live Networks, Inc.  All rights reserved
// A demo application that receives a UDP multicast stream, replicates it (using the "StreamReplicator" class),
// and retransmits one replica stream to another (multicast or unicast) address & port,
// and writes the other replica stream to a file.
//
// main program

#include <liveMedia.hh>
#include "BasicUsageEnvironment.hh"
#include "GroupsockHelper.hh"

UsageEnvironment* env;

// To receive a "source-specific multicast" (SSM) stream, uncomment this:
//#define USE_SSM 1

void startReplicaUDPSink(StreamReplicator* replicator, char const* outputAddressStr, portNumBits outputPortNum); // forward
void startReplicaFileSink(StreamReplicator* replicator, char const* outputFileName); // forward

int main(int argc, char** argv) {
  // Begin by setting up our usage environment:
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  env = BasicUsageEnvironment::createNew(*scheduler);

  // Create a 'groupsock' for the input multicast group,port:
  char const* inputAddressStr
#ifdef USE_SSM
    = "232.255.42.42";
#else
    = "239.255.42.42";
#endif
  struct in_addr inputAddress;
  inputAddress.s_addr = our_inet_addr(inputAddressStr);

  Port const inputPort(8888);
  unsigned char const inputTTL = 0; // we're only reading from this mcast group

#ifdef USE_SSM
  char* sourceAddressStr = "aaa.bbb.ccc.ddd";
                           // replace this with the real source address
  struct in_addr sourceFilterAddress;
  sourceFilterAddress.s_addr = our_inet_addr(sourceAddressStr);

  Groupsock inputGroupsock(*env, inputAddress, sourceFilterAddress, inputPort);
#else
  Groupsock inputGroupsock(*env, inputAddress, inputPort, inputTTL);
#endif

  // Then create a liveMedia 'source' object, encapsulating this groupsock:
  FramedSource* source = BasicUDPSource::createNew(*env, &inputGroupsock);

  // And feed this into a 'stream replicator':
  StreamReplicator* replicator = StreamReplicator::createNew(*env, source);

  // Then create a network (UDP) 'sink' object to receive a replica of the input stream, and start it.
  // If you wish, you can duplicate this line - with different network addresses and ports - to create multiple output UDP streams:
  startReplicaUDPSink(replicator, "239.255.43.43", 4444);

  // Then create a file 'sink' object to receive a replica of the input stream, and start it.
  // If you wish, you can duplicate this line - with a different file name - to create multiple output files:
  startReplicaFileSink(replicator, "test.out");

  // Finally, enter the 'event loop' (which is where most of the 'real work' in a LIVE555-based application gets done):
  env->taskScheduler().doEventLoop(); // does not return

  return 0; // only to prevent compiler warning
}

void startReplicaUDPSink(StreamReplicator* replicator, char const* outputAddressStr, portNumBits outputPortNum) {
  // Begin by creating an input stream from our replicator:
  FramedSource* source = replicator->createStreamReplica();

  // Create a 'groupsock' for the destination address and port:
  struct in_addr outputAddress;
  outputAddress.s_addr = our_inet_addr(outputAddressStr);

  Port const outputPort(outputPortNum);
  unsigned char const outputTTL = 255;

  Groupsock* outputGroupsock = new Groupsock(*env, outputAddress, outputPort, outputTTL);

  // Then create a liveMedia 'sink' object, encapsulating this groupsock:
  unsigned const maxPacketSize = 65536; // allow for large UDP packets
  MediaSink* sink = BasicUDPSink::createNew(*env, outputGroupsock, maxPacketSize);

  // Now, start playing, feeding the sink object from the source:
  sink->startPlaying(*source, NULL, NULL);
}

void startReplicaFileSink(StreamReplicator* replicator, char const* outputFileName) {
  // Begin by creating an input stream from our replicator:
  FramedSource* source = replicator->createStreamReplica();

  // Then create a 'file sink' object to receive thie replica stream:
  MediaSink* sink = FileSink::createNew(*env, outputFileName);

  // Now, start playing, feeding the sink object from the source:
  sink->startPlaying(*source, NULL, NULL);
}
