From 9631b79e861ace61a1f09b2863dfefadbaf9687e Mon Sep 17 00:00:00 2001
From: Thulinma <jaron@vietors.com>
Date: Thu, 28 Jan 2016 11:27:26 +0100
Subject: [PATCH] Removed DTSC::Stream and DTSC::Ring classes - no longer in
 use anywhere.

---
 lib/dtsc.cpp     | 525 -----------------------------------------------
 lib/dtsc.h       |  57 -----
 lib/dtscmeta.cpp |   2 +-
 lib/flv_tag.cpp  | 126 ------------
 lib/flv_tag.h    |   2 -
 lib/json.h       |   7 -
 6 files changed, 1 insertion(+), 718 deletions(-)

diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp
index fb5966ad..4f25c07c 100644
--- a/lib/dtsc.cpp
+++ b/lib/dtsc.cpp
@@ -10,531 +10,6 @@ char DTSC::Magic_Header[] = "DTSC";
 char DTSC::Magic_Packet[] = "DTPD";
 char DTSC::Magic_Packet2[] = "DTP2";
 
-/// Initializes a DTSC::Stream with only one packet buffer.
-DTSC::Stream::Stream() {
-  datapointertype = DTSC::INVALID;
-  buffercount = 1;
-  buffertime = 0;
-}
-
-/// Initializes a DTSC::Stream with a minimum of rbuffers packet buffers.
-/// The actual buffer count may not at all times be the requested amount.
-DTSC::Stream::Stream(unsigned int rbuffers, unsigned int bufferTime) {
-  datapointertype = DTSC::INVALID;
-  if (rbuffers < 1) {
-    rbuffers = 1;
-  }
-  buffercount = rbuffers;
-  buffertime = bufferTime;
-}
-
-/// This function does nothing, it's supposed to be overridden.
-/// It will be called right before a buffer position is deleted.
-void DTSC::Stream::deletionCallback(livePos deleting) {}
-
-/// Returns the time in milliseconds of the last received packet.
-/// This is _not_ the time this packet was received, only the stored time.
-unsigned int DTSC::Stream::getTime() {
-  if (!buffers.size()) {
-    return 0;
-  }
-  return buffers.rbegin()->second["time"].asInt();
-}
-
-/// Attempts to parse a packet from the given std::string buffer.
-/// Returns true if successful, removing the parsed part from the buffer string.
-/// Returns false if invalid or not enough data is in the buffer.
-/// \arg buffer The std::string buffer to attempt to parse.
-bool DTSC::Stream::parsePacket(std::string & buffer) {
-  uint32_t len;
-  static bool syncing = false;
-  if (buffer.length() > 8) {
-    if (memcmp(buffer.c_str(), DTSC::Magic_Header, 4) == 0) {
-      len = ntohl(((uint32_t *)buffer.c_str())[1]);
-      if (buffer.length() < len + 8) {
-        return false;
-      }
-      unsigned int i = 0;
-      JSON::Value meta;
-      JSON::fromDTMI((unsigned char *)buffer.c_str() + 8, len, i, meta);
-      metadata = Meta(meta);
-      buffer.erase(0, len + 8);
-      if (buffer.length() <= 8) {
-        return false;
-      }
-    }
-    int version = 0;
-    if (memcmp(buffer.c_str(), DTSC::Magic_Packet, 4) == 0) {
-      version = 1;
-    }
-    if (memcmp(buffer.c_str(), DTSC::Magic_Packet2, 4) == 0) {
-      version = 2;
-    }
-    if (version) {
-      len = ntohl(((uint32_t *)buffer.c_str())[1]);
-      if (buffer.length() < len + 8) {
-        return false;
-      }
-      JSON::Value newPack;
-      unsigned int i = 0;
-      if (version == 1) {
-        JSON::fromDTMI((unsigned char *)buffer.c_str() + 8, len, i, newPack);
-      }
-      if (version == 2) {
-        JSON::fromDTMI2((unsigned char *)buffer.c_str() + 8, len, i, newPack);
-      }
-      buffer.erase(0, len + 8);
-      addPacket(newPack);
-      syncing = false;
-      return true;
-    }
-#if DEBUG >= DLVL_WARN
-    if (!syncing) {
-      DEBUG_MSG(DLVL_WARN, "Invalid DTMI data detected - re-syncing");
-      syncing = true;
-    }
-#endif
-    size_t magic_search = buffer.find(Magic_Packet);
-    size_t magic_search2 = buffer.find(Magic_Packet2);
-    if (magic_search2 == std::string::npos) {
-      if (magic_search == std::string::npos) {
-        buffer.clear();
-      } else {
-        buffer.erase(0, magic_search);
-      }
-    } else {
-      buffer.erase(0, magic_search2);
-    }
-  }
-  return false;
-}
-
-/// Attempts to parse a packet from the given Socket::Buffer.
-/// Returns true if successful, removing the parsed part from the buffer.
-/// Returns false if invalid or not enough data is in the buffer.
-/// \arg buffer The Socket::Buffer to attempt to parse.
-bool DTSC::Stream::parsePacket(Socket::Buffer & buffer) {
-  uint32_t len;
-  static bool syncing = false;
-  if (buffer.available(8)) {
-    std::string header_bytes = buffer.copy(8);
-    if (memcmp(header_bytes.c_str(), DTSC::Magic_Header, 4) == 0) {
-      len = ntohl(((uint32_t *)header_bytes.c_str())[1]);
-      if (!buffer.available(len + 8)) {
-        return false;
-      }
-      unsigned int i = 0;
-      std::string wholepacket = buffer.remove(len + 8);
-      JSON::Value meta;
-      JSON::fromDTMI((unsigned char *)wholepacket.c_str() + 8, len, i, meta);
-      addMeta(meta);
-      //recursively calls itself until failure or data packet instead of header
-      return parsePacket(buffer);
-    }
-    int version = 0;
-    if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet, 4) == 0) {
-      version = 1;
-    }
-    if (memcmp(header_bytes.c_str(), DTSC::Magic_Packet2, 4) == 0) {
-      version = 2;
-    }
-    if (version) {
-      len = ntohl(((uint32_t *)header_bytes.c_str())[1]);
-      if (!buffer.available(len + 8)) {
-        return false;
-      }
-      JSON::Value newPack;
-      unsigned int i = 0;
-      std::string wholepacket = buffer.remove(len + 8);
-      if (version == 1) {
-        JSON::fromDTMI((unsigned char *)wholepacket.c_str() + 8, len, i, newPack);
-      }
-      if (version == 2) {
-        JSON::fromDTMI2((unsigned char *)wholepacket.c_str() + 8, len, i, newPack);
-      }
-      addPacket(newPack);
-      syncing = false;
-      return true;
-    }
-#if DEBUG >= DLVL_WARN
-    if (!syncing) {
-      DEBUG_MSG(DLVL_WARN, "Invalid DTMI data detected - syncing");
-      syncing = true;
-    }
-#endif
-    buffer.get().clear();
-  }
-  return false;
-}
-
-/// Adds a keyframe packet to all tracks, so the stream can be fully played.
-void DTSC::Stream::endStream() {
-  if (!metadata.tracks.size()) {
-    return;
-  }
-  for (std::map<unsigned int, Track>::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) {
-    JSON::Value newPack;
-    newPack["time"] = (long long)it->second.lastms;
-    newPack["trackid"] = it->first;
-    newPack["keyframe"] = 1ll;
-    newPack["data"] = "";
-    addPacket(newPack);
-  }
-}
-
-/// Blocks until either the stream has metadata available or the sourceSocket errors.
-/// This function is intended to be run before any commands are sent and thus will not throw away anything important.
-/// It will time out after 3 seconds, disconnecting the sourceSocket.
-void DTSC::Stream::waitForMeta(Socket::Connection & sourceSocket, bool closeOnError){
-  bool wasBlocking = sourceSocket.isBlocking();
-  sourceSocket.setBlocking(false);
-  //cancel the attempt after 5000 milliseconds
-  long long int start = Util::getMS();
-  while (!metadata && sourceSocket.connected() && Util::getMS() - start < 3000) {
-    //we have data? attempt to read header
-    if (sourceSocket.Received().size()) {
-      //return value is ignored because we're not interested in data packets, just metadata.
-      parsePacket(sourceSocket.Received());
-    }
-    //still no header? check for more data
-    if (!metadata) {
-      if (sourceSocket.spool()) {
-        //more received? attempt to read
-        //return value is ignored because we're not interested in data packets, just metadata.
-        parsePacket(sourceSocket.Received());
-      } else {
-        //nothing extra to receive? wait a bit and retry
-        Util::sleep(10);
-      }
-    }
-  }
-  sourceSocket.setBlocking(wasBlocking);
-  //if the timeout has passed, close the socket
-  if (Util::getMS() - start >= 3000 && closeOnError){
-    sourceSocket.close();
-    //and optionally print a debug message that this happened
-    DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for metadata");
-  }
-}
-
-/// Blocks until either the stream encounters a pause mark or the sourceSocket errors.
-/// This function is intended to be run after the 'q' command is sent, throwing away superfluous packets.
-/// It will time out after 5 seconds, disconnecting the sourceSocket.
-void DTSC::Stream::waitForPause(Socket::Connection & sourceSocket) {
-  bool wasBlocking = sourceSocket.isBlocking();
-  sourceSocket.setBlocking(false);
-  //cancel the attempt after 5000 milliseconds
-  long long int start = Util::getMS();
-  while (lastType() != DTSC::PAUSEMARK && sourceSocket.connected() && Util::getMS() - start < 5000) {
-    //we have data? parse it
-    if (sourceSocket.Received().size()) {
-      //return value is ignored because we're not interested.
-      parsePacket(sourceSocket.Received());
-    }
-    //still no pause mark? check for more data
-    if (lastType() != DTSC::PAUSEMARK) {
-      if (sourceSocket.spool()) {
-        //more received? attempt to read
-        //return value is ignored because we're not interested in data packets, just metadata.
-        parsePacket(sourceSocket.Received());
-      } else {
-        //nothing extra to receive? wait a bit and retry
-        Util::sleep(10);
-      }
-    }
-  }
-  sourceSocket.setBlocking(wasBlocking);
-  //if the timeout has passed, close the socket
-  if (Util::getMS() - start >= 5000) {
-    sourceSocket.close();
-    //and optionally print a debug message that this happened
-    DEBUG_MSG(DLVL_DEVEL, "Timing out while waiting for pause break");
-  }
-}
-
-/// Resets the stream by clearing the buffers and keyframes, making sure to call the deletionCallback first.
-void DTSC::Stream::resetStream() {
-  for (std::map<livePos, JSON::Value >::iterator it = buffers.begin(); it != buffers.end(); it++) {
-    deletionCallback(it->first);
-  }
-  buffers.clear();
-  keyframes.clear();
-}
-
-/// Adds a set of metadata to the steam.
-/// This is implemented by simply replacing the current metadata.
-/// This effectively resets the stream.
-void DTSC::Stream::addMeta(JSON::Value & newMeta) {
-  metadata = Meta(newMeta);
-}
-
-/// Adds a single DTSC packet to the stream, updating the internal metadata if needed.
-void DTSC::Stream::addPacket(JSON::Value & newPack) {
-  livePos newPos;
-  newPos.trackID = newPack["trackid"].asInt();
-  newPos.seekTime = newPack["time"].asInt();
-  if (!metadata.tracks.count(newPos.trackID) && (!newPack.isMember("mark") || newPack["mark"].asStringRef() != "pause")) {
-    return;
-  }
-  if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime()) {
-    resetStream();
-  }
-  while (buffers.count(newPos) > 0) {
-    newPos.seekTime++;
-  }
-  while (buffercount == 1 && buffers.size() > 0) {
-    cutOneBuffer();
-  }
-  buffers[newPos] = newPack;
-  datapointertype = INVALID;
-  std::string tmp = "";
-  if (newPack.isMember("trackid") && newPack["trackid"].asInt() > 0) {
-    tmp = metadata.tracks[newPack["trackid"].asInt()].type;
-  }
-  if (newPack.isMember("datatype")) {
-    tmp = newPack["datatype"].asStringRef();
-  }
-  if (tmp == "video") {
-    datapointertype = VIDEO;
-  }
-  if (tmp == "audio") {
-    datapointertype = AUDIO;
-  }
-  if (tmp == "meta") {
-    datapointertype = META;
-  }
-  if (tmp == "pause_marker" || (newPack.isMember("mark") && newPack["mark"].asStringRef() == "pause")) {
-    datapointertype = PAUSEMARK;
-  }
-  if (buffercount > 1) {
-    metadata.update(newPack);
-    if (newPack.isMember("keyframe") || (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime() == newPos.seekTime) {
-      keyframes[newPos.trackID].insert(newPos);
-    }
-    metadata.live = true;
-    //throw away buffers if buffer time is met
-    int trid = buffers.begin()->first.trackID;
-    int firstTime = buffers.begin()->first.seekTime;
-    int lastTime = buffers.rbegin()->first.seekTime - buffertime;
-    while ((!metadata.tracks[trid].keys.size() && firstTime < lastTime) || (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys.rbegin()->getTime() < lastTime) || (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime)) {
-      cutOneBuffer();
-      trid = buffers.begin()->first.trackID;
-      firstTime = buffers.begin()->first.seekTime;
-    }
-    metadata.bufferWindow = buffertime;
-  }
-
-}
-
-/// Deletes a the first part of the buffer, updating the keyframes list and metadata as required.
-/// Will print a warning if a track has less than 2 keyframes left because of this.
-void DTSC::Stream::cutOneBuffer() {
-  if (!buffers.size()) {
-    return;
-  }
-  int trid = buffers.begin()->first.trackID;
-  long long unsigned int delTime = buffers.begin()->first.seekTime;
-  if (buffercount > 1) {
-    while (keyframes[trid].size() > 0 && keyframes[trid].begin()->seekTime <= delTime) {
-      keyframes[trid].erase(keyframes[trid].begin());
-    }
-    while (metadata.tracks[trid].keys.size() && (long long unsigned int)metadata.tracks[trid].keys[0].getTime() <= delTime) {
-      for (int i = 0; i < metadata.tracks[trid].keys[0].getParts(); i++) {
-        metadata.tracks[trid].parts.pop_front();
-      }
-      metadata.tracks[trid].keys.pop_front();
-    }
-    if (metadata.tracks[trid].keys.size()) {
-      metadata.tracks[trid].firstms = metadata.tracks[trid].keys[0].getTime();
-      //delete fragments of which the beginning can no longer be reached
-      while (metadata.tracks[trid].fragments.size() && metadata.tracks[trid].fragments[0].getNumber() < metadata.tracks[trid].keys[0].getNumber()) {
-        metadata.tracks[trid].fragments.pop_front();
-        //increase the missed fragments counter
-        metadata.tracks[trid].missedFrags++;
-      }
-    } else {
-      metadata.tracks[trid].fragments.clear();
-    }
-  }
-  deletionCallback(buffers.begin()->first);
-  buffers.erase(buffers.begin());
-}
-
-/// Returns a direct pointer to the data attribute of the last received packet, if available.
-/// Returns NULL if no valid pointer or packet is available.
-std::string & DTSC::Stream::lastData() {
-  return buffers.rbegin()->second["data"].strVal;
-}
-
-/// Returns the packet in this buffer number.
-/// \arg num Buffer number.
-JSON::Value & DTSC::Stream::getPacket(livePos num) {
-  static JSON::Value empty;
-  if (buffers.find(num) == buffers.end()) {
-    return empty;
-  }
-  return buffers[num];
-}
-
-JSON::Value & DTSC::Stream::getPacket() {
-  return buffers.begin()->second;
-}
-
-/// Returns the type of the last received packet.
-DTSC::datatype DTSC::Stream::lastType() {
-  return datapointertype;
-}
-
-/// Returns true if the current stream contains at least one video track.
-bool DTSC::Stream::hasVideo() {
-  for (std::map<unsigned int, Track>::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) {
-    if (it->second.type == "video") {
-      return true;
-    }
-  }
-  return false;
-}
-
-/// Returns true if the current stream contains at least one audio track.
-bool DTSC::Stream::hasAudio() {
-  for (std::map<unsigned int, Track>::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) {
-    if (it->second.type == "audio") {
-      return true;
-    }
-  }
-  return false;
-}
-
-void DTSC::Stream::setBufferTime(unsigned int ms) {
-  buffertime = ms;
-}
-
-std::string & DTSC::Stream::outPacket() {
-  static std::string emptystring;
-  if (!buffers.size() || !buffers.rbegin()->second.isObject()) {
-    return emptystring;
-  }
-  return buffers.rbegin()->second.toNetPacked();
-}
-
-/// Returns a packed DTSC packet, ready to sent over the network.
-std::string & DTSC::Stream::outPacket(livePos num) {
-  static std::string emptystring;
-  if (buffers.find(num) == buffers.end() || !buffers[num].isObject()) return emptystring;
-  return buffers[num].toNetPacked();
-}
-
-/// Returns a packed DTSC header, ready to sent over the network.
-std::string & DTSC::Stream::outHeader() {
-  return metadata.toJSON().toNetPacked();
-}
-
-/// Constructs a new Ring, at the given buffer position.
-/// \arg v Position for buffer.
-DTSC::Ring::Ring(livePos v) {
-  b = v;
-  waiting = false;
-  starved = false;
-  updated = false;
-  playCount = 0;
-}
-
-/// Requests a new Ring, which will be created and added to the internal Ring list.
-/// This Ring will be kept updated so it always points to valid data or has the starved boolean set.
-/// Don't forget to call dropRing() for all requested Ring classes that are no longer neccessary!
-DTSC::Ring * DTSC::Stream::getRing() {
-  livePos tmp = buffers.begin()->first;
-  std::map<int, std::set<livePos> >::iterator it;
-  for (it = keyframes.begin(); it != keyframes.end(); it++) {
-    if ((*it->second.begin()).seekTime > tmp.seekTime) {
-      tmp = *it->second.begin();
-    }
-  }
-  return new DTSC::Ring(tmp);
-}
-
-/// Deletes a given out Ring class from memory and internal Ring list.
-/// Checks for NULL pointers and invalid pointers, silently discarding them.
-void DTSC::Stream::dropRing(DTSC::Ring * ptr) {
-  if (ptr) {
-    delete ptr;
-  }
-}
-
-/// Returns 0 if seeking is possible, -1 if the wanted frame is too old, 1 if the wanted frame is too new.
-/// This function looks in the header - not in the buffered data itself.
-int DTSC::Stream::canSeekms(unsigned int ms) {
-  bool too_late = false;
-  //no tracks? Frame too new by definition.
-  if (!metadata.tracks.size()) {
-    return 1;
-  }
-  //loop trough all the tracks
-  for (std::map<unsigned int, Track>::iterator it = metadata.tracks.begin(); it != metadata.tracks.end(); it++) {
-    if (it->second.keys.size()) {
-      if (it->second.keys[0].getTime() <= ms && it->second.keys[it->second.keys.size() - 1].getTime() >= ms) {
-        return 0;
-      }
-      if (it->second.keys[0].getTime() > ms) {
-        too_late = true;
-      }
-    }
-  }
-  //did we spot a track already past this point? return too late.
-  if (too_late) {
-    return -1;
-  }
-  //otherwise, assume not available yet
-  return 1;
-}
-
-DTSC::livePos DTSC::Stream::msSeek(unsigned int ms, std::set<unsigned int> & allowedTracks) {
-  std::set<unsigned int> seekTracks = allowedTracks;
-  livePos result = buffers.begin()->first;
-  for (std::set<unsigned int>::iterator it = allowedTracks.begin(); it != allowedTracks.end(); it++) {
-    if (metadata.tracks[*it].type == "video") {
-      int trackNo = *it;
-      seekTracks.clear();
-      seekTracks.insert(trackNo);
-      break;
-    }
-  }
-  for (std::map<livePos, JSON::Value>::iterator bIt = buffers.begin(); bIt != buffers.end(); bIt++) {
-    if (seekTracks.find(bIt->first.trackID) != seekTracks.end()) {
-      //  if (bIt->second.isMember("keyframe")){
-      result = bIt->first;
-      if (bIt->first.seekTime >= ms) {
-        return result;
-      }
-      //}
-    }
-  }
-  return result;
-}
-
-/// Returns whether the current position is the last currently available position within allowedTracks.
-/// Simply returns the result of getNext(pos, allowedTracks) == pos
-bool DTSC::Stream::isNewest(DTSC::livePos & pos, std::set<unsigned int> & allowedTracks) {
-  return getNext(pos, allowedTracks) == pos;
-}
-
-/// Returns the next available position within allowedTracks, or the current position if no next is availble.
-DTSC::livePos DTSC::Stream::getNext(DTSC::livePos & pos, std::set<unsigned int> & allowedTracks) {
-  std::map<livePos, JSON::Value>::iterator iter = buffers.upper_bound(pos);
-  while (iter != buffers.end()) {
-    if (allowedTracks.count(iter->first.trackID)) {
-      return iter->first;
-    }
-    iter++;
-  }
-  return pos;
-}
-
-/// Properly cleans up the object for erasing.
-/// Drops all Ring classes that have been given out.
-DTSC::Stream::~Stream() {
-}
-
 DTSC::File::File() {
   F = 0;
   buffer = malloc(4);
diff --git a/lib/dtsc.h b/lib/dtsc.h
index 0707f424..cf6752f1 100644
--- a/lib/dtsc.h
+++ b/lib/dtsc.h
@@ -166,19 +166,6 @@ namespace DTSC {
     unsigned int trackID;
   };
 
-  /// A part from the DTSC::Stream ringbuffer.
-  /// Holds information about a buffer that will stay consistent
-  class Ring {
-    public:
-      Ring(livePos v);
-      livePos b;
-      //volatile unsigned int b; ///< Holds current number of buffer. May and is intended to change unexpectedly!
-      volatile bool waiting; ///< If true, this Ring is currently waiting for a buffer fill.
-      volatile bool starved; ///< If true, this Ring can no longer receive valid data.
-      volatile bool updated; ///< If true, this Ring should write a new header.
-      volatile int playCount;
-  };
-
 
   ///\brief Basic class for storage of data associated with single DTSC packets, a.k.a. parts.
   class Part {
@@ -374,49 +361,5 @@ namespace DTSC {
   };
   //FileWriter
 
-  /// Holds temporary data for a DTSC stream and provides functions to utilize it.
-  /// Optionally also acts as a ring buffer of a certain requested size.
-  /// If ring buffering mode is enabled, it will automatically grow in size to always contain at least one keyframe.
-  class Stream {
-    public:
-      Stream();
-      virtual ~Stream();
-      Stream(unsigned int buffers, unsigned int bufferTime = 0);
-      Meta metadata;
-      JSON::Value & getPacket();
-      JSON::Value & getPacket(livePos num);
-      datatype lastType();
-      std::string & lastData();
-      bool hasVideo();
-      bool hasAudio();
-      bool parsePacket(std::string & buffer);
-      bool parsePacket(Socket::Buffer & buffer);
-      std::string & outPacket();
-      std::string & outPacket(livePos num);
-      std::string & outHeader();
-      Ring * getRing();
-      unsigned int getTime();
-      void dropRing(Ring * ptr);
-      int canSeekms(unsigned int ms);
-      livePos msSeek(unsigned int ms, std::set<unsigned int> & allowedTracks);
-      void setBufferTime(unsigned int ms);
-      bool isNewest(DTSC::livePos & pos, std::set<unsigned int> & allowedTracks);
-      DTSC::livePos getNext(DTSC::livePos & pos, std::set<unsigned int> & allowedTracks);
-      void endStream();
-      void waitForMeta(Socket::Connection & sourceSocket, bool closeOnError = true);
-      void waitForPause(Socket::Connection & sourceSocket);
-    protected:
-      void cutOneBuffer();
-      void resetStream();
-      std::map<livePos, JSON::Value> buffers;
-      std::map<int, std::set<livePos> > keyframes;
-      virtual void addPacket(JSON::Value & newPack);
-      virtual void addMeta(JSON::Value & newMeta);
-      datatype datapointertype;
-      unsigned int buffercount;
-      unsigned int buffertime;
-      std::map<unsigned int, std::string> trackMapping;
-      virtual void deletionCallback(livePos deleting);
-  };
 }
 
diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp
index ff8f598a..4125c47c 100644
--- a/lib/dtscmeta.cpp
+++ b/lib/dtscmeta.cpp
@@ -646,7 +646,7 @@ namespace DTSC {
     return "";
   }
 
-  /// Sets result to a pointer to the string, and strlen to the lenght of it.
+  /// Sets result to a pointer to the string, and strlen to the length of it.
   /// Sets both to zero if this isn't a DTSC string value.
   /// Attempts absolutely no conversion.
   void Scan::getString(char *& result, unsigned int & strlen) {
diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp
index 0dc418ca..9d2289e5 100644
--- a/lib/flv_tag.cpp
+++ b/lib/flv_tag.cpp
@@ -360,14 +360,6 @@ FLV::Tag & FLV::Tag::operator=(const FLV::Tag & O) {
   return *this;
 } //assignment operator
 
-/// FLV loader function from DTSC.
-/// Takes the DTSC data and makes it into FLV.
-bool FLV::Tag::DTSCLoader(DTSC::Stream & S) {
-  std::string tmp = S.getPacket().toNetPacked();
-  DTSC::Packet tmpPack(tmp.data(), tmp.size());
-  return DTSCLoader(tmpPack, S.metadata.tracks[S.getPacket()["trackid"].asInt()]);
-}
-
 bool FLV::Tag::DTSCLoader(DTSC::Packet & packData, DTSC::Track & track) {
   std::string meta_str;
   len = 0;
@@ -698,124 +690,6 @@ bool FLV::Tag::DTSCMetaInit(DTSC::Meta & M, std::set<long unsigned int> & selTra
   return true;
 }
 
-/// FLV metadata loader function from DTSC.
-/// Takes the DTSC metadata and makes it into FLV.
-/// Assumes metadata is available - so check before calling!
-bool FLV::Tag::DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Track & audioRef) {
-  //Unknown? Assume AAC.
-  if (audioRef.codec == "?") {
-    audioRef.codec = "AAC";
-  }
-  //Unknown? Assume H264.
-  if (videoRef.codec == "?") {
-    videoRef.codec = "H264";
-  }
-
-  AMF::Object amfdata("root", AMF::AMF0_DDV_CONTAINER);
-
-  amfdata.addContent(AMF::Object("", "onMetaData"));
-  amfdata.addContent(AMF::Object("", AMF::AMF0_ECMA_ARRAY));
-  if (S.metadata.vod) {
-    amfdata.getContentP(1)->addContent(AMF::Object("duration", videoRef.lastms / 1000, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("moovPosition", 40, AMF::AMF0_NUMBER));
-    AMF::Object keys("keyframes", AMF::AMF0_OBJECT);
-    keys.addContent(AMF::Object("filepositions", AMF::AMF0_STRICT_ARRAY));
-    keys.addContent(AMF::Object("times", AMF::AMF0_STRICT_ARRAY));
-    int total_byterate = 0;
-    if (videoRef.trackID > 0) {
-      total_byterate += videoRef.bps;
-    }
-    if (audioRef.trackID > 0) {
-      total_byterate += audioRef.bps;
-    }
-    for (unsigned long long i = 0; i < videoRef.lastms / 1000; ++i) { //for each second in the file
-      keys.getContentP(0)->addContent(AMF::Object("", i * total_byterate, AMF::AMF0_NUMBER)); //multiply by byterate for fake byte positions
-      keys.getContentP(1)->addContent(AMF::Object("", i, AMF::AMF0_NUMBER)); //seconds
-    }
-    amfdata.getContentP(1)->addContent(keys);
-  }
-  if (videoRef.trackID > 0) {
-    amfdata.getContentP(1)->addContent(AMF::Object("hasVideo", 1, AMF::AMF0_BOOL));
-    if (videoRef.codec == "H264") {
-      amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", (std::string)"avc1"));
-    }
-    if (videoRef.codec == "VP6") {
-      amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 4, AMF::AMF0_NUMBER));
-    }
-    if (videoRef.codec == "H263") {
-      amfdata.getContentP(1)->addContent(AMF::Object("videocodecid", 2, AMF::AMF0_NUMBER));
-    }
-    amfdata.getContentP(1)->addContent(AMF::Object("width", videoRef.width, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("height", videoRef.height, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("videoframerate", (double)videoRef.fpks / 1000.0, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("videodatarate", (double)videoRef.bps * 128.0, AMF::AMF0_NUMBER));
-  }
-  if (audioRef.trackID > 0) {
-    amfdata.getContentP(1)->addContent(AMF::Object("hasAudio", 1, AMF::AMF0_BOOL));
-    amfdata.getContentP(1)->addContent(AMF::Object("audiodelay", 0, AMF::AMF0_NUMBER));
-    if (audioRef.codec == "AAC") {
-      amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp4a"));
-    }
-    if (audioRef.codec == "MP3") {
-      amfdata.getContentP(1)->addContent(AMF::Object("audiocodecid", (std::string)"mp3"));
-    }
-    amfdata.getContentP(1)->addContent(AMF::Object("audiochannels", audioRef.channels, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("audiosamplerate", audioRef.rate, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("audiosamplesize", audioRef.size, AMF::AMF0_NUMBER));
-    amfdata.getContentP(1)->addContent(AMF::Object("audiodatarate", (double)audioRef.bps * 128.0, AMF::AMF0_NUMBER));
-  }
-  AMF::Object trinfo = AMF::Object("trackinfo", AMF::AMF0_STRICT_ARRAY);
-  int i = 0;
-  if (audioRef) {
-    trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT));
-    trinfo.getContentP(i)->addContent(AMF::Object("length", ((double)audioRef.lastms) * ((double)audioRef.rate), AMF::AMF0_NUMBER));
-    trinfo.getContentP(i)->addContent(AMF::Object("timescale", audioRef.rate, AMF::AMF0_NUMBER));
-    trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY));
-    if (audioRef.codec == "AAC") {
-      trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp4a"));
-    }
-    if (audioRef.codec == "MP3") {
-      trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"mp3"));
-    }
-    ++i;
-  }
-  if (videoRef) {
-    trinfo.addContent(AMF::Object("", AMF::AMF0_OBJECT));
-    trinfo.getContentP(i)->addContent(
-      AMF::Object("length", ((double)videoRef.lastms / 1000) * ((double)videoRef.fpks / 1000.0), AMF::AMF0_NUMBER));
-    trinfo.getContentP(i)->addContent(AMF::Object("timescale", ((double)videoRef.fpks / 1000.0), AMF::AMF0_NUMBER));
-    trinfo.getContentP(i)->addContent(AMF::Object("sampledescription", AMF::AMF0_STRICT_ARRAY));
-    if (videoRef.codec == "H264") {
-      trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"avc1"));
-    }
-    if (videoRef.codec == "VP6") {
-      trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"vp6"));
-    }
-    if (videoRef.codec == "H263") {
-      trinfo.getContentP(i)->getContentP(2)->addContent(AMF::Object("sampletype", (std::string)"h263"));
-    }
-    ++i;
-  }
-  amfdata.getContentP(1)->addContent(trinfo);
-
-  std::string tmp = amfdata.Pack();
-  len = tmp.length() + 15;
-  if (len <= 0 || !checkBufferSize()) {
-    return false;
-  }
-  memcpy(data + 11, tmp.data(), len - 15);
-  setLen();
-  data[0] = 0x12;
-  data[1] = ((len - 15) >> 16) & 0xFF;
-  data[2] = ((len - 15) >> 8) & 0xFF;
-  data[3] = (len - 15) & 0xFF;
-  data[8] = 0;
-  data[9] = 0;
-  data[10] = 0;
-  tagTime(0);
-  return true;
-}
-
 /// FLV loader function from chunk.
 /// Copies the contents and wraps it in a FLV header.
 bool FLV::Tag::ChunkLoader(const RTMPStream::Chunk & O) {
diff --git a/lib/flv_tag.h b/lib/flv_tag.h
index 15837753..b91fe53e 100644
--- a/lib/flv_tag.h
+++ b/lib/flv_tag.h
@@ -47,12 +47,10 @@ namespace FLV {
       ~Tag(); ///< Generic destructor.
       //loader functions
       bool ChunkLoader(const RTMPStream::Chunk & O);
-      bool DTSCLoader(DTSC::Stream & S);
       bool DTSCLoader(DTSC::Packet & packData, DTSC::Track & track);
       bool DTSCVideoInit(DTSC::Track & video);
       bool DTSCAudioInit(DTSC::Track & audio);
       bool DTSCMetaInit(DTSC::Meta & M, std::set<long unsigned int> & selTracks);
-      bool DTSCMetaInit(DTSC::Stream & S, DTSC::Track & videoRef, DTSC::Track & audioRef);
       JSON::Value toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, unsigned int reTrack = 0);
       bool MemLoader(char * D, unsigned int S, unsigned int & P);
       bool FileLoader(FILE * f);
diff --git a/lib/json.h b/lib/json.h
index 958ee5d6..37390033 100644
--- a/lib/json.h
+++ b/lib/json.h
@@ -8,11 +8,6 @@
 #include <vector>
 #include "socket.h"
 
-//empty definition of DTSC::Stream so it can be a friend.
-namespace DTSC {
-  class Stream;
-}
-
 /// JSON-related classes and functions
 namespace JSON {
 
@@ -33,8 +28,6 @@ namespace JSON {
       std::deque<Value*> arrVal;
       std::map<std::string, Value*> objVal;
     public:
-      //friends
-      friend class DTSC::Stream; //for access to strVal
       //constructors/destructors
       Value();
       ~Value();