diff --git a/lib/mp4.cpp b/lib/mp4.cpp
index 93bd5b96..cec0c5a6 100644
--- a/lib/mp4.cpp
+++ b/lib/mp4.cpp
@@ -2,10 +2,10 @@
 #include <string.h> //for memcpy
 #include <arpa/inet.h> //for htonl and friends
 #include "mp4.h"
+#include "mp4_adobe.h"
+#include "mp4_ms.h"
+#include "mp4_generic.h"
 #include "json.h"
-#include "defines.h"
-
-#define Int64 uint64_t
 
 /// Contains all MP4 format related code.
 namespace MP4 {
@@ -119,7 +119,7 @@ namespace MP4 {
   }
 
   /// Attempts to typecast this Box to a more specific type and call the toPrettyString() function of that type.
-  /// If this failed, it will print out a message saying pretty-printing is not implemented for that boxtype.
+  /// If this failed, it will print out a message saying pretty-printing is not implemented for boxtype.
   std::string Box::toPrettyString(uint32_t indent){
     switch (ntohl( *((int*)(data + 4)))){ //type is at this address
       case 0x6D666864:
@@ -285,7 +285,6 @@ namespace MP4 {
     }
     std::string retval = std::string(indent, ' ') + "Unimplemented pretty-printing for box " + std::string(data + 4, 4) + "\n";
     /// \todo Implement hexdump for unimplemented boxes?
-    //retval += 
     return retval;
   }
 
@@ -413,7 +412,7 @@ namespace MP4 {
   /// Sets the 64 bits integer at the given index.
   /// Attempts to resize the data pointer if the index is out of range.
   /// Fails silently if resizing failed.
-  void Box::setInt64(Int64 newData, size_t index){
+  void Box::setInt64(uint64_t newData, size_t index){
     index += payloadOffset;
     if (index + 7 >= boxedSize()){
       if ( !reserve(index, 0, 8)){
@@ -427,7 +426,7 @@ namespace MP4 {
   /// Gets the 64 bits integer at the given index.
   /// Attempts to resize the data pointer if the index is out of range.
   /// Returns zero if resizing failed.
-  Int64 Box::getInt64(size_t index){
+  uint64_t Box::getInt64(size_t index){
     index += payloadOffset;
     if (index + 7 >= boxedSize()){
       if ( !reserve(index, 0, 8)){
@@ -435,7 +434,7 @@ namespace MP4 {
       }
       setInt64(0, index - payloadOffset);
     }
-    Int64 result = ntohl(((int*)(data + index))[0]);
+    uint64_t result = ntohl(((int*)(data + index))[0]);
     result <<= 32;
     result += ntohl(((int*)(data + index))[1]);
     return result;
@@ -542,7 +541,7 @@ namespace MP4 {
     }
     if (current < wanted){
       //make bigger
-      if (boxedSize() + (wanted - current) > (size_t)data_size){
+      if (boxedSize() + (wanted - current) > data_size){
         //realloc if managed, otherwise fail
         if ( !managed){
           return false;
@@ -640,12 +639,16 @@ namespace MP4 {
     return getBox(tempLoc);
   }
   
-  std::string containerBox::toPrettyContainerString(uint32_t indent, std::string boxName){
+  std::string containerBox::toPrettyString(uint32_t indent){
     std::stringstream r;
-    r << std::string(indent, ' ') << boxName <<" (" << boxedSize() << ")" << std::endl;
-    for (unsigned int i = 0; i < getContentCount(); i++){
-      Box curBox = MP4::Box(getContent(i).asBox(), false);
+    r << std::string(indent, ' ') << "[" << getType() <<"] Container Box (" << boxedSize() << ")" << std::endl;
+    Box curBox;
+    int tempLoc = 0;
+    int contentCount = getContentCount();
+    for (int i = 0; i < contentCount; i++){
+      curBox = getContent(i);
       r << curBox.toPrettyString(indent + 1);
+      tempLoc += getBoxLen(tempLoc);
     }
     return r.str();
   }
@@ -684,7 +687,7 @@ namespace MP4 {
       return ret;
     }
     unsigned int i = 0;
-    unsigned int tempLoc = 4;
+    int tempLoc = 4;
     while (i < no){
       tempLoc += getBoxLen(tempLoc);
       i++;
@@ -706,4048 +709,4 @@ namespace MP4 {
     }
     return r.str();
   }
-  
-  ABST::ABST(){
-    memcpy(data + 4, "abst", 4);
-    setVersion(0);
-    setFlags(0);
-    setBootstrapinfoVersion(0);
-    setProfile(0);
-    setLive(1);
-    setUpdate(0);
-    setTimeScale(1000);
-    setCurrentMediaTime(0);
-    setSmpteTimeCodeOffset(0);
-    std::string empty;
-    setMovieIdentifier(empty);
-    setInt8(0, 30); //set serverentrycount to 0
-    setInt8(0, 31); //set qualityentrycount to 0
-    setDrmData(empty);
-    setMetaData(empty);
-  }
-
-  void ABST::setVersion(char newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  char ABST::getVersion(){
-    return getInt8(0);
-  }
-
-  void ABST::setFlags(uint32_t newFlags){
-    setInt24(newFlags, 1);
-  }
-
-  uint32_t ABST::getFlags(){
-    return getInt24(1);
-  }
-
-  void ABST::setBootstrapinfoVersion(uint32_t newVersion){
-    setInt32(newVersion, 4);
-  }
-
-  uint32_t ABST::getBootstrapinfoVersion(){
-    return getInt32(4);
-  }
-
-  void ABST::setProfile(char newProfile){
-    //profile = bit 1 and 2 of byte 8.
-    setInt8((getInt8(8) & 0x3F) + ((newProfile & 0x03) << 6), 8);
-  }
-
-  char ABST::getProfile(){
-    return (getInt8(8) & 0xC0);
-  }
-  ;
-
-  void ABST::setLive(bool newLive){
-    //live = bit 4 of byte 8.
-    setInt8((getInt8(8) & 0xDF) + (newLive ? 0x10 : 0), 8);
-  }
-
-  bool ABST::getLive(){
-    return (getInt8(8) & 0x10);
-  }
-
-  void ABST::setUpdate(bool newUpdate){
-    //update = bit 5 of byte 8.
-    setInt8((getInt8(8) & 0xEF) + (newUpdate ? 0x08 : 0), 8);
-  }
-
-  bool ABST::getUpdate(){
-    return (getInt8(8) & 0x08);
-  }
-
-  void ABST::setTimeScale(uint32_t newScale){
-    setInt32(newScale, 9);
-  }
-
-  uint32_t ABST::getTimeScale(){
-    return getInt32(9);
-  }
-
-  void ABST::setCurrentMediaTime(Int64 newTime){
-    setInt64(newTime, 13);
-  }
-
-  Int64 ABST::getCurrentMediaTime(){
-    return getInt64(13);
-  }
-
-  void ABST::setSmpteTimeCodeOffset(Int64 newTime){
-    setInt64(newTime, 21);
-  }
-
-  Int64 ABST::getSmpteTimeCodeOffset(){
-    return getInt64(21);
-  }
-
-  void ABST::setMovieIdentifier(std::string & newIdentifier){
-    setString(newIdentifier, 29);
-  }
-
-  char* ABST::getMovieIdentifier(){
-    return getString(29);
-  }
-
-  uint32_t ABST::getServerEntryCount(){
-    int countLoc = 29 + getStringLen(29) + 1;
-    return getInt8(countLoc);
-  }
-
-  void ABST::setServerEntry(std::string & newEntry, uint32_t no){
-    int countLoc = 29 + getStringLen(29) + 1;
-    int tempLoc = countLoc + 1;
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getInt8(countLoc)){
-      int amount = no + 1 - getInt8(countLoc);
-      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
-        return;
-      };
-      memset(data + payloadOffset + tempLoc, 0, amount);
-      setInt8(no + 1, countLoc); //set new qualityEntryCount
-      tempLoc += no - i;
-    }
-    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
-    setString(newEntry, tempLoc);
-  }
-
-  ///\return Empty string if no > serverEntryCount(), serverEntry[no] otherwise.
-  const char* ABST::getServerEntry(uint32_t no){
-    if (no + 1 > getServerEntryCount()){
-      return "";
-    }
-    int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of first entry
-    for (unsigned int i = 0; i < no; i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getString(tempLoc);
-  }
-
-  uint32_t ABST::getQualityEntryCount(){
-    int countLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      countLoc += getStringLen(countLoc) + 1;
-    }
-    return getInt8(countLoc);
-  }
-
-  void ABST::setQualityEntry(std::string & newEntry, uint32_t no){
-    int countLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      countLoc += getStringLen(countLoc) + 1;
-    }
-    int tempLoc = countLoc + 1;
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getInt8(countLoc)){
-      int amount = no + 1 - getInt8(countLoc);
-      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
-        return;
-      };
-      memset(data + payloadOffset + tempLoc, 0, amount);
-      setInt8(no + 1, countLoc); //set new qualityEntryCount
-      tempLoc += no - i;
-    }
-    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
-    setString(newEntry, tempLoc);
-  }
-
-  const char* ABST::getQualityEntry(uint32_t no){
-    if (no > getQualityEntryCount()){
-      return "";
-    }
-    int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of serverentries;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += 1; //first qualityentry
-    for (unsigned int i = 0; i < no; i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getString(tempLoc);
-  }
-
-  void ABST::setDrmData(std::string newDrm){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    setString(newDrm, tempLoc);
-  }
-
-  char* ABST::getDrmData(){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getString(tempLoc);
-  }
-
-  void ABST::setMetaData(std::string newMetaData){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1;
-    setString(newMetaData, tempLoc);
-  }
-
-  char* ABST::getMetaData(){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1;
-    return getString(tempLoc);
-  }
-
-  uint32_t ABST::getSegmentRunTableCount(){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    return getInt8(tempLoc);
-  }
-
-  void ABST::setSegmentRunTable(ASRT & newSegment, uint32_t no){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    int countLoc = tempLoc;
-    tempLoc++; //skip segmentRuntableCount
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getInt8(countLoc)){
-      int amount = no + 1 - getInt8(countLoc);
-      if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){
-        return;
-      };
-      //set empty erro boxes as contents
-      for (int j = 0; j < amount; ++j){
-        memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
-      }
-      setInt8(no + 1, countLoc); //set new count
-      tempLoc += (no - i) * 8;
-    }
-    //now, tempLoc is at position for string number no, and we have at least an erro box reserved.
-    setBox(newSegment, tempLoc);
-  }
-
-  ASRT & ABST::getSegmentRunTable(uint32_t no){
-    static Box result;
-    if (no > getSegmentRunTableCount()){
-      static Box res;
-      return (ASRT&)res;
-    }
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    tempLoc++; //segmentRuntableCount
-    for (unsigned int i = 0; i < no; ++i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    return (ASRT&)getBox(tempLoc);
-  }
-
-  uint32_t ABST::getFragmentRunTableCount(){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    return getInt8(tempLoc);
-  }
-
-  void ABST::setFragmentRunTable(AFRT & newFragment, uint32_t no){
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    int countLoc = tempLoc;
-    tempLoc++;
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getInt8(countLoc)){
-      unsigned int amount = no + 1 - getInt8(countLoc);
-      if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){
-        return;
-      };
-      //set empty erro boxes as contents
-      for (unsigned int j = 0; j < amount; ++j){
-        memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
-      }
-      setInt8(no + 1, countLoc); //set new count
-      tempLoc += (no - i) * 8;
-    }
-    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
-    setBox(newFragment, tempLoc);
-  }
-
-  AFRT & ABST::getFragmentRunTable(uint32_t no){
-    static Box result;
-    if (no >= getFragmentRunTableCount()){
-      static Box res;
-      return (AFRT&)res;
-    }
-    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += getStringLen(tempLoc) + 1; //DrmData
-    tempLoc += getStringLen(tempLoc) + 1; //MetaData
-    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    tempLoc++;
-    for (unsigned int i = 0; i < no; i++){
-      tempLoc += getBoxLen(tempLoc);
-    }
-    return (AFRT&)getBox(tempLoc);
-  }
-
-  std::string ABST::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[abst] Bootstrap Info (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "BootstrapinfoVersion " << getBootstrapinfoVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "Profile " << (int)getProfile() << std::endl;
-    if (getLive()){
-      r << std::string(indent + 1, ' ') << "Live" << std::endl;
-    }else{
-      r << std::string(indent + 1, ' ') << "Recorded" << std::endl;
-    }
-    if (getUpdate()){
-      r << std::string(indent + 1, ' ') << "Update" << std::endl;
-    }else{
-      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl;
-    r << std::string(indent + 1, ' ') << "CurrMediaTime " << getCurrentMediaTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "SmpteTimeCodeOffset " << getSmpteTimeCodeOffset() << std::endl;
-    r << std::string(indent + 1, ' ') << "MovieIdentifier " << getMovieIdentifier() << std::endl;
-    r << std::string(indent + 1, ' ') << "ServerEntryTable (" << getServerEntryCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getServerEntryCount(); i++){
-      r << std::string(indent + 2, ' ') << i << ": " << getServerEntry(i) << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "DrmData " << getDrmData() << std::endl;
-    r << std::string(indent + 1, ' ') << "MetaData " << getMetaData() << std::endl;
-    r << std::string(indent + 1, ' ') << "SegmentRunTableEntries (" << getSegmentRunTableCount() << ")" << std::endl;
-    for (uint32_t i = 0; i < getSegmentRunTableCount(); i++){
-      r << ((Box)getSegmentRunTable(i)).toPrettyString(indent + 2);
-    }
-    r << std::string(indent + 1, ' ') + "FragmentRunTableEntries (" << getFragmentRunTableCount() << ")" << std::endl;
-    for (uint32_t i = 0; i < getFragmentRunTableCount(); i++){
-      r << ((Box)getFragmentRunTable(i)).toPrettyString(indent + 2);
-    }
-    return r.str();
-  }
-
-  AFRT::AFRT(){
-    memcpy(data + 4, "afrt", 4);
-    setVersion(0);
-    setUpdate(0);
-    setTimeScale(1000);
-  }
-
-  void AFRT::setVersion(char newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  uint32_t AFRT::getVersion(){
-    return getInt8(0);
-  }
-
-  void AFRT::setUpdate(uint32_t newUpdate){
-    setInt24(newUpdate, 1);
-  }
-
-  uint32_t AFRT::getUpdate(){
-    return getInt24(1);
-  }
-
-  void AFRT::setTimeScale(uint32_t newScale){
-    setInt32(newScale, 4);
-  }
-
-  uint32_t AFRT::getTimeScale(){
-    return getInt32(4);
-  }
-
-  uint32_t AFRT::getQualityEntryCount(){
-    return getInt8(8);
-  }
-
-  void AFRT::setQualityEntry(std::string & newEntry, uint32_t no){
-    int countLoc = 8;
-    int tempLoc = countLoc + 1;
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getQualityEntryCount() && i < no; ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getQualityEntryCount()){
-      int amount = no + 1 - getQualityEntryCount();
-      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
-        return;
-      };
-      memset(data + payloadOffset + tempLoc, 0, amount);
-      setInt8(no + 1, countLoc); //set new qualityEntryCount
-      tempLoc += no - i;
-    }
-    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
-    setString(newEntry, tempLoc);
-  }
-
-  const char* AFRT::getQualityEntry(uint32_t no){
-    if (no + 1 > getQualityEntryCount()){
-      return "";
-    }
-    int tempLoc = 9; //position of first quality entry
-    for (unsigned int i = 0; i < no; i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getString(tempLoc);
-  }
-
-  uint32_t AFRT::getFragmentRunCount(){
-    int tempLoc = 9;
-    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getInt32(tempLoc);
-  }
-
-  void AFRT::setFragmentRun(afrt_runtable newRun, uint32_t no){
-    int tempLoc = 9;
-    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    int countLoc = tempLoc;
-    tempLoc += 4;
-    for (unsigned int i = 0; i < no; i++){
-      if (i + 1 > getInt32(countLoc)){
-        setInt32(0, tempLoc);
-        setInt64(0, tempLoc + 4);
-        setInt32(1, tempLoc + 12);
-      }
-      if (getInt32(tempLoc + 12) == 0){
-        tempLoc += 17;
-      }else{
-        tempLoc += 16;
-      }
-    }
-    setInt32(newRun.firstFragment, tempLoc);
-    setInt64(newRun.firstTimestamp, tempLoc + 4);
-    setInt32(newRun.duration, tempLoc + 12);
-    if (newRun.duration == 0){
-      setInt8(newRun.discontinuity, tempLoc + 16);
-    }
-    if (getInt32(countLoc) < no + 1){
-      setInt32(no + 1, countLoc);
-    }
-  }
-
-  afrt_runtable AFRT::getFragmentRun(uint32_t no){
-    afrt_runtable res;
-    if (no > getFragmentRunCount()){
-      return res;
-    }
-    int tempLoc = 9;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += 4;
-    for (unsigned int i = 0; i < no; i++){
-      if (getInt32(tempLoc + 12) == 0){
-        tempLoc += 17;
-      }else{
-        tempLoc += 16;
-      }
-    }
-    res.firstFragment = getInt32(tempLoc);
-    res.firstTimestamp = getInt64(tempLoc + 4);
-    res.duration = getInt32(tempLoc + 12);
-    if (res.duration){
-      res.discontinuity = getInt8(tempLoc + 16);
-    }else{
-      res.discontinuity = 0;
-    }
-    return res;
-  }
-
-  std::string AFRT::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[afrt] Fragment Run Table (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl;
-    if (getUpdate()){
-      r << std::string(indent + 1, ' ') << "Update" << std::endl;
-    }else{
-      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl;
-    r << std::string(indent + 1, ' ') << "QualitySegmentUrlModifiers (" << getQualityEntryCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "FragmentRunEntryTable (" << getFragmentRunCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getFragmentRunCount(); i++){
-      afrt_runtable myRun = getFragmentRun(i);
-      if (myRun.duration){
-        r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
-            << "s, " << ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl;
-      }else{
-        r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
-            << "s, discontinuity type " << myRun.discontinuity << std::endl;
-      }
-    }
-    return r.str();
-  }
-
-  ASRT::ASRT(){
-    memcpy(data + 4, "asrt", 4);
-    setVersion(0);
-    setUpdate(0);
-  }
-
-  void ASRT::setVersion(char newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  uint32_t ASRT::getVersion(){
-    return getInt8(0);
-  }
-
-  void ASRT::setUpdate(uint32_t newUpdate){
-    setInt24(newUpdate, 1);
-  }
-
-  uint32_t ASRT::getUpdate(){
-    return getInt24(1);
-  }
-
-  uint32_t ASRT::getQualityEntryCount(){
-    return getInt8(4);
-  }
-
-  void ASRT::setQualityEntry(std::string & newEntry, uint32_t no){
-    int countLoc = 4;
-    int tempLoc = countLoc + 1;
-    //attempt to reach the wanted position
-    unsigned int i;
-    for (i = 0; i < getQualityEntryCount() && i < no; ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    //we are now either at the end, or at the right position
-    //let's reserve any unreserved space...
-    if (no + 1 > getQualityEntryCount()){
-      int amount = no + 1 - getQualityEntryCount();
-      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
-        return;
-      };
-      memset(data + payloadOffset + tempLoc, 0, amount);
-      setInt8(no + 1, countLoc); //set new qualityEntryCount
-      tempLoc += no - i;
-    }
-    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
-    setString(newEntry, tempLoc);
-  }
-
-  const char* ASRT::getQualityEntry(uint32_t no){
-    if (no > getQualityEntryCount()){
-      return "";
-    }
-    int tempLoc = 5; //position of qualityentry count;
-    for (unsigned int i = 0; i < no; i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getString(tempLoc);
-  }
-
-  uint32_t ASRT::getSegmentRunEntryCount(){
-    int tempLoc = 5; //position of qualityentry count;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    return getInt32(tempLoc);
-  }
-
-  void ASRT::setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no){
-    int tempLoc = 5; //position of qualityentry count;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    int countLoc = tempLoc;
-    tempLoc += 4 + no * 8;
-    if (no + 1 > getInt32(countLoc)){
-      setInt32(no + 1, countLoc); //set new qualityEntryCount
-    }
-    setInt32(firstSegment, tempLoc);
-    setInt32(fragmentsPerSegment, tempLoc + 4);
-  }
-
-  asrt_runtable ASRT::getSegmentRun(uint32_t no){
-    asrt_runtable res;
-    if (no >= getSegmentRunEntryCount()){
-      return res;
-    }
-    int tempLoc = 5; //position of qualityentry count;
-    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
-      tempLoc += getStringLen(tempLoc) + 1;
-    }
-    tempLoc += 4 + 8 * no;
-    res.firstSegment = getInt32(tempLoc);
-    res.fragmentsPerSegment = getInt32(tempLoc + 4);
-    return res;
-  }
-
-  std::string ASRT::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[asrt] Segment Run Table (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl;
-    if (getUpdate()){
-      r << std::string(indent + 1, ' ') << "Update" << std::endl;
-    }else{
-      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
-      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
-    }
-    r << std::string(indent + 1, ' ') << "SegmentRunEntryTable (" << getSegmentRunEntryCount() << ")" << std::endl;
-    for (unsigned int i = 0; i < getSegmentRunEntryCount(); i++){
-      r << std::string(indent + 2, ' ') << i << ": First=" << getSegmentRun(i).firstSegment << ", FragmentsPerSegment="
-          << getSegmentRun(i).fragmentsPerSegment << std::endl;
-    }
-    return r.str();
-  }
-
-  MFHD::MFHD(){
-    memcpy(data + 4, "mfhd", 4);
-    setInt32(0, 0);
-  }
-
-  void MFHD::setSequenceNumber(uint32_t newSequenceNumber){
-    setInt32(newSequenceNumber, 4);
-  }
-
-  uint32_t MFHD::getSequenceNumber(){
-    return getInt32(4);
-  }
-
-  std::string MFHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[mfhd] Movie Fragment Header (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "SequenceNumber " << getSequenceNumber() << std::endl;
-    return r.str();
-  }
-
-  MOOF::MOOF(){
-    memcpy(data + 4, "moof", 4);
-  }
-
-  std::string MOOF::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[moof] Movie Fragment Box"));
-  }
-
-  TRAF::TRAF(){
-    memcpy(data + 4, "traf", 4);
-  }
-
-  uint32_t TRAF::getContentCount(){
-    int res = 0;
-    unsigned int tempLoc = 0;
-    while (tempLoc < boxedSize() - 8){
-      res++;
-      tempLoc += getBoxLen(tempLoc);
-    }
-    return res;
-  }
-
-  void TRAF::setContent(Box & newContent, uint32_t no){
-    int tempLoc = 0;
-    unsigned int contentCount = getContentCount();
-    for (unsigned int i = 0; i < no; i++){
-      if (i < contentCount){
-        tempLoc += getBoxLen(tempLoc);
-      }else{
-        if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){
-          return;
-        };
-        memset(data + tempLoc, 0, (no - contentCount) * 8);
-        tempLoc += (no - contentCount) * 8;
-        break;
-      }
-    }
-    setBox(newContent, tempLoc);
-  }
-
-  Box & TRAF::getContent(uint32_t no){
-    static Box ret = Box((char*)"\000\000\000\010erro", false);
-    if (no > getContentCount()){
-      return ret;
-    }
-    unsigned int i = 0;
-    int tempLoc = 0;
-    while (i < no){
-      tempLoc += getBoxLen(tempLoc);
-      i++;
-    }
-    return getBox(tempLoc);
-  }
-
-  std::string TRAF::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[traf] Track Fragment Box (" << boxedSize() << ")" << std::endl;
-    int contentCount = getContentCount();
-    for (int i = 0; i < contentCount; i++){
-      Box curBox = Box(getContent(i).asBox(),false);
-      r << curBox.toPrettyString(indent + 1);
-    }
-    return r.str();
-  }
-
-  TRUN::TRUN(){
-    memcpy(data + 4, "trun", 4);
-  }
-
-  void TRUN::setFlags(uint32_t newFlags){
-    setInt24(newFlags, 1);
-  }
-
-  uint32_t TRUN::getFlags(){
-    return getInt24(1);
-  }
-
-  void TRUN::setDataOffset(uint32_t newOffset){
-    if (getFlags() & trundataOffset){
-      setInt32(newOffset, 8);
-    }
-  }
-
-  uint32_t TRUN::getDataOffset(){
-    if (getFlags() & trundataOffset){
-      return getInt32(8);
-    }else{
-      return 0;
-    }
-  }
-
-  void TRUN::setFirstSampleFlags(uint32_t newSampleFlags){
-    if ( !(getFlags() & trunfirstSampleFlags)){
-      return;
-    }
-    if (getFlags() & trundataOffset){
-      setInt32(newSampleFlags, 12);
-    }else{
-      setInt32(newSampleFlags, 8);
-    }
-  }
-
-  uint32_t TRUN::getFirstSampleFlags(){
-    if ( !(getFlags() & trunfirstSampleFlags)){
-      return 0;
-    }
-    if (getFlags() & trundataOffset){
-      return getInt32(12);
-    }else{
-      return getInt32(8);
-    }
-  }
-
-  uint32_t TRUN::getSampleInformationCount(){
-    return getInt32(4);
-  }
-
-  void TRUN::setSampleInformation(trunSampleInformation newSample, uint32_t no){
-    uint32_t flags = getFlags();
-    uint32_t sampInfoSize = 0;
-    if (flags & trunsampleDuration){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleSize){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleFlags){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleOffsets){
-      sampInfoSize += 4;
-    }
-    uint32_t offset = 8;
-    if (flags & trundataOffset){
-      offset += 4;
-    }
-    if (flags & trunfirstSampleFlags){
-      offset += 4;
-    }
-    uint32_t innerOffset = 0;
-    if (flags & trunsampleDuration){
-      setInt32(newSample.sampleDuration, offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleSize){
-      setInt32(newSample.sampleSize, offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleFlags){
-      setInt32(newSample.sampleFlags, offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleOffsets){
-      setInt32(newSample.sampleOffset, offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (getSampleInformationCount() < no + 1){
-      setInt32(no + 1, 4);
-    }
-  }
-
-  trunSampleInformation TRUN::getSampleInformation(uint32_t no){
-    trunSampleInformation ret;
-    ret.sampleDuration = 0;
-    ret.sampleSize = 0;
-    ret.sampleFlags = 0;
-    ret.sampleOffset = 0;
-    if (getSampleInformationCount() < no + 1){
-      return ret;
-    }
-    uint32_t flags = getFlags();
-    uint32_t sampInfoSize = 0;
-    if (flags & trunsampleDuration){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleSize){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleFlags){
-      sampInfoSize += 4;
-    }
-    if (flags & trunsampleOffsets){
-      sampInfoSize += 4;
-    }
-    uint32_t offset = 8;
-    if (flags & trundataOffset){
-      offset += 4;
-    }
-    if (flags & trunfirstSampleFlags){
-      offset += 4;
-    }
-    uint32_t innerOffset = 0;
-    if (flags & trunsampleDuration){
-      ret.sampleDuration = getInt32(offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleSize){
-      ret.sampleSize = getInt32(offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleFlags){
-      ret.sampleFlags = getInt32(offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    if (flags & trunsampleOffsets){
-      ret.sampleOffset = getInt32(offset + no * sampInfoSize + innerOffset);
-      innerOffset += 4;
-    }
-    return ret;
-  }
-
-  std::string TRUN::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[trun] Track Fragment Run (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl;
-
-    uint32_t flags = getFlags();
-    r << std::string(indent + 1, ' ') << "Flags";
-    if (flags & trundataOffset){
-      r << " dataOffset";
-    }
-    if (flags & trunfirstSampleFlags){
-      r << " firstSampleFlags";
-    }
-    if (flags & trunsampleDuration){
-      r << " sampleDuration";
-    }
-    if (flags & trunsampleSize){
-      r << " sampleSize";
-    }
-    if (flags & trunsampleFlags){
-      r << " sampleFlags";
-    }
-    if (flags & trunsampleOffsets){
-      r << " sampleOffsets";
-    }
-    r << std::endl;
-
-    if (flags & trundataOffset){
-      r << std::string(indent + 1, ' ') << "Data Offset " << getDataOffset() << std::endl;
-    }
-    if (flags & trundataOffset){
-      r << std::string(indent + 1, ' ') << "Sample Flags" << prettySampleFlags(getFirstSampleFlags()) << std::endl;
-    }
-
-    r << std::string(indent + 1, ' ') << "SampleInformation (" << getSampleInformationCount() << "):" << std::endl;
-    for (unsigned int i = 0; i < getSampleInformationCount(); ++i){
-      r << std::string(indent + 2, ' ') << "[" << i << "] ";
-      trunSampleInformation samp = getSampleInformation(i);
-      if (flags & trunsampleDuration){
-        r << "Duration=" << samp.sampleDuration << " ";
-      }
-      if (flags & trunsampleSize){
-        r << "Size=" << samp.sampleSize << " ";
-      }
-      if (flags & trunsampleFlags){
-        r << "Flags=" << prettySampleFlags(samp.sampleFlags) << " ";
-      }
-      if (flags & trunsampleOffsets){
-        r << "Offset=" << samp.sampleOffset << " ";
-      }
-      r << std::endl;
-    }
-
-    return r.str();
-  }
-
-  std::string prettySampleFlags(uint32_t flag){
-    std::stringstream r;
-    if (flag & noIPicture){
-      r << " noIPicture";
-    }
-    if (flag & isIPicture){
-      r << " isIPicture";
-    }
-    if (flag & noDisposable){
-      r << " noDisposable";
-    }
-    if (flag & isDisposable){
-      r << " isDisposable";
-    }
-    if (flag & isRedundant){
-      r << " isRedundant";
-    }
-    if (flag & noRedundant){
-      r << " noRedundant";
-    }
-    if (flag & noKeySample){
-      r << " noKeySample";
-    }else{
-      r << " isKeySample";
-    }
-    return r.str();
-  }
-
-  TFHD::TFHD(){
-    memcpy(data + 4, "tfhd", 4);
-  }
-
-  void TFHD::setFlags(uint32_t newFlags){
-    setInt24(newFlags, 1);
-  }
-
-  uint32_t TFHD::getFlags(){
-    return getInt24(1);
-  }
-
-  void TFHD::setTrackID(uint32_t newID){
-    setInt32(newID, 4);
-  }
-
-  uint32_t TFHD::getTrackID(){
-    return getInt32(4);
-  }
-
-  void TFHD::setBaseDataOffset(uint64_t newOffset){
-    if (getFlags() & tfhdBaseOffset){
-      setInt64(newOffset, 8);
-    }
-  }
-
-  uint64_t TFHD::getBaseDataOffset(){
-    if (getFlags() & tfhdBaseOffset){
-      return getInt64(8);
-    }else{
-      return 0;
-    }
-  }
-
-  void TFHD::setSampleDescriptionIndex(uint32_t newIndex){
-    if ( !(getFlags() & tfhdSampleDesc)){
-      return;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    setInt32(newIndex, offset);
-  }
-
-  uint32_t TFHD::getSampleDescriptionIndex(){
-    if ( !(getFlags() & tfhdSampleDesc)){
-      return 0;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    return getInt32(offset);
-  }
-
-  void TFHD::setDefaultSampleDuration(uint32_t newDuration){
-    if ( !(getFlags() & tfhdSampleDura)){
-      return;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    setInt32(newDuration, offset);
-  }
-
-  uint32_t TFHD::getDefaultSampleDuration(){
-    if ( !(getFlags() & tfhdSampleDura)){
-      return 0;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    return getInt32(offset);
-  }
-
-  void TFHD::setDefaultSampleSize(uint32_t newSize){
-    if ( !(getFlags() & tfhdSampleSize)){
-      return;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleDura){
-      offset += 4;
-    }
-    setInt32(newSize, offset);
-  }
-
-  uint32_t TFHD::getDefaultSampleSize(){
-    if ( !(getFlags() & tfhdSampleSize)){
-      return 0;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleDura){
-      offset += 4;
-    }
-    return getInt32(offset);
-  }
-
-  void TFHD::setDefaultSampleFlags(uint32_t newFlags){
-    if ( !(getFlags() & tfhdSampleFlag)){
-      return;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleDura){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleSize){
-      offset += 4;
-    }
-    setInt32(newFlags, offset);
-  }
-
-  uint32_t TFHD::getDefaultSampleFlags(){
-    if ( !(getFlags() & tfhdSampleFlag)){
-      return 0;
-    }
-    int offset = 8;
-    if (getFlags() & tfhdBaseOffset){
-      offset += 8;
-    }
-    if (getFlags() & tfhdSampleDesc){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleDura){
-      offset += 4;
-    }
-    if (getFlags() & tfhdSampleSize){
-      offset += 4;
-    }
-    return getInt32(offset);
-  }
-
-  std::string TFHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[tfhd] Track Fragment Header (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl;
-
-    uint32_t flags = getFlags();
-    r << std::string(indent + 1, ' ') << "Flags";
-    if (flags & tfhdBaseOffset){
-      r << " BaseOffset";
-    }
-    if (flags & tfhdSampleDesc){
-      r << " SampleDesc";
-    }
-    if (flags & tfhdSampleDura){
-      r << " SampleDura";
-    }
-    if (flags & tfhdSampleSize){
-      r << " SampleSize";
-    }
-    if (flags & tfhdSampleFlag){
-      r << " SampleFlag";
-    }
-    if (flags & tfhdNoDuration){
-      r << " NoDuration";
-    }
-    r << std::endl;
-
-    r << std::string(indent + 1, ' ') << "TrackID " << getTrackID() << std::endl;
-
-    if (flags & tfhdBaseOffset){
-      r << std::string(indent + 1, ' ') << "Base Offset " << getBaseDataOffset() << std::endl;
-    }
-    if (flags & tfhdSampleDesc){
-      r << std::string(indent + 1, ' ') << "Sample Description Index " << getSampleDescriptionIndex() << std::endl;
-    }
-    if (flags & tfhdSampleDura){
-      r << std::string(indent + 1, ' ') << "Default Sample Duration " << getDefaultSampleDuration() << std::endl;
-    }
-    if (flags & tfhdSampleSize){
-      r << std::string(indent + 1, ' ') << "Default Same Size " << getDefaultSampleSize() << std::endl;
-    }
-    if (flags & tfhdSampleFlag){
-      r << std::string(indent + 1, ' ') << "Default Sample Flags " << prettySampleFlags(getDefaultSampleFlags()) << std::endl;
-    }
-
-    return r.str();
-  }
-
-  AFRA::AFRA(){
-    memcpy(data + 4, "afra", 4);
-    setInt32(0, 9); //entrycount = 0
-    setFlags(0);
-  }
-
-  void AFRA::setVersion(uint32_t newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  uint32_t AFRA::getVersion(){
-    return getInt8(0);
-  }
-
-  void AFRA::setFlags(uint32_t newFlags){
-    setInt24(newFlags, 1);
-  }
-
-  uint32_t AFRA::getFlags(){
-    return getInt24(1);
-  }
-
-  void AFRA::setLongIDs(bool newVal){
-    if (newVal){
-      setInt8((getInt8(4) & 0x7F) + 0x80, 4);
-    }else{
-      setInt8((getInt8(4) & 0x7F), 4);
-    }
-  }
-
-  bool AFRA::getLongIDs(){
-    return getInt8(4) & 0x80;
-  }
-
-  void AFRA::setLongOffsets(bool newVal){
-    if (newVal){
-      setInt8((getInt8(4) & 0xBF) + 0x40, 4);
-    }else{
-      setInt8((getInt8(4) & 0xBF), 4);
-    }
-  }
-
-  bool AFRA::getLongOffsets(){
-    return getInt8(4) & 0x40;
-  }
-
-  void AFRA::setGlobalEntries(bool newVal){
-    if (newVal){
-      setInt8((getInt8(4) & 0xDF) + 0x20, 4);
-    }else{
-      setInt8((getInt8(4) & 0xDF), 4);
-    }
-  }
-
-  bool AFRA::getGlobalEntries(){
-    return getInt8(4) & 0x20;
-  }
-
-  void AFRA::setTimeScale(uint32_t newVal){
-    setInt32(newVal, 5);
-  }
-
-  uint32_t AFRA::getTimeScale(){
-    return getInt32(5);
-  }
-
-  uint32_t AFRA::getEntryCount(){
-    return getInt32(9);
-  }
-
-  void AFRA::setEntry(afraentry newEntry, uint32_t no){
-    int entrysize = 12;
-    if (getLongOffsets()){
-      entrysize = 16;
-    }
-    setInt64(newEntry.time, 13 + entrysize * no);
-    if (getLongOffsets()){
-      setInt64(newEntry.offset, 21 + entrysize * no);
-    }else{
-      setInt32(newEntry.offset, 21 + entrysize * no);
-    }
-    if (no + 1 > getEntryCount()){
-      setInt32(no + 1, 9);
-    }
-  }
-
-  afraentry AFRA::getEntry(uint32_t no){
-    afraentry ret;
-    int entrysize = 12;
-    if (getLongOffsets()){
-      entrysize = 16;
-    }
-    ret.time = getInt64(13 + entrysize * no);
-    if (getLongOffsets()){
-      ret.offset = getInt64(21 + entrysize * no);
-    }else{
-      ret.offset = getInt32(21 + entrysize * no);
-    }
-    return ret;
-  }
-
-  uint32_t AFRA::getGlobalEntryCount(){
-    if ( !getGlobalEntries()){
-      return 0;
-    }
-    int entrysize = 12;
-    if (getLongOffsets()){
-      entrysize = 16;
-    }
-    return getInt32(13 + entrysize * getEntryCount());
-  }
-
-  void AFRA::setGlobalEntry(globalafraentry newEntry, uint32_t no){
-    int offset = 13 + 12 * getEntryCount() + 4;
-    if (getLongOffsets()){
-      offset = 13 + 16 * getEntryCount() + 4;
-    }
-    int entrysize = 20;
-    if (getLongIDs()){
-      entrysize += 4;
-    }
-    if (getLongOffsets()){
-      entrysize += 8;
-    }
-
-    setInt64(newEntry.time, offset + entrysize * no);
-    if (getLongIDs()){
-      setInt32(newEntry.segment, offset + entrysize * no + 8);
-      setInt32(newEntry.fragment, offset + entrysize * no + 12);
-    }else{
-      setInt16(newEntry.segment, offset + entrysize * no + 8);
-      setInt16(newEntry.fragment, offset + entrysize * no + 10);
-    }
-    if (getLongOffsets()){
-      setInt64(newEntry.afraoffset, offset + entrysize * no + entrysize - 16);
-      setInt64(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 8);
-    }else{
-      setInt32(newEntry.afraoffset, offset + entrysize * no + entrysize - 8);
-      setInt32(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 4);
-    }
-
-    if (getInt32(offset - 4) < no + 1){
-      setInt32(no + 1, offset - 4);
-    }
-  }
-
-  globalafraentry AFRA::getGlobalEntry(uint32_t no){
-    globalafraentry ret;
-    int offset = 13 + 12 * getEntryCount() + 4;
-    if (getLongOffsets()){
-      offset = 13 + 16 * getEntryCount() + 4;
-    }
-    int entrysize = 20;
-    if (getLongIDs()){
-      entrysize += 4;
-    }
-    if (getLongOffsets()){
-      entrysize += 8;
-    }
-
-    ret.time = getInt64(offset + entrysize * no);
-    if (getLongIDs()){
-      ret.segment = getInt32(offset + entrysize * no + 8);
-      ret.fragment = getInt32(offset + entrysize * no + 12);
-    }else{
-      ret.segment = getInt16(offset + entrysize * no + 8);
-      ret.fragment = getInt16(offset + entrysize * no + 10);
-    }
-    if (getLongOffsets()){
-      ret.afraoffset = getInt64(offset + entrysize * no + entrysize - 16);
-      ret.offsetfromafra = getInt64(offset + entrysize * no + entrysize - 8);
-    }else{
-      ret.afraoffset = getInt32(offset + entrysize * no + entrysize - 8);
-      ret.offsetfromafra = getInt32(offset + entrysize * no + entrysize - 4);
-    }
-    return ret;
-  }
-
-  std::string AFRA::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[afra] Fragment Random Access (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "Flags " << getFlags() << std::endl;
-    r << std::string(indent + 1, ' ') << "Long IDs " << getLongIDs() << std::endl;
-    r << std::string(indent + 1, ' ') << "Long Offsets " << getLongOffsets() << std::endl;
-    r << std::string(indent + 1, ' ') << "Global Entries " << getGlobalEntries() << std::endl;
-    r << std::string(indent + 1, ' ') << "TimeScale " << getTimeScale() << std::endl;
-
-    uint32_t count = getEntryCount();
-    r << std::string(indent + 1, ' ') << "Entries (" << count << ") " << std::endl;
-    for (uint32_t i = 0; i < count; ++i){
-      afraentry tmpent = getEntry(i);
-      r << std::string(indent + 1, ' ') << i << ": Time " << tmpent.time << ", Offset " << tmpent.offset << std::endl;
-    }
-
-    if (getGlobalEntries()){
-      count = getGlobalEntryCount();
-      r << std::string(indent + 1, ' ') << "Global Entries (" << count << ") " << std::endl;
-      for (uint32_t i = 0; i < count; ++i){
-        globalafraentry tmpent = getGlobalEntry(i);
-        r << std::string(indent + 1, ' ') << i << ": T " << tmpent.time << ", S" << tmpent.segment << "F" << tmpent.fragment << ", "
-            << tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl;
-      }
-    }
-
-    return r.str();
-  }
-
-  AVCC::AVCC(){
-    memcpy(data + 4, "avcC", 4);
-    setInt8(0xFF, 4); //reserved + 4-bytes NAL length
-  }
-
-  void AVCC::setVersion(uint32_t newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  uint32_t AVCC::getVersion(){
-    return getInt8(0);
-  }
-
-  void AVCC::setProfile(uint32_t newProfile){
-    setInt8(newProfile, 1);
-  }
-
-  uint32_t AVCC::getProfile(){
-    return getInt8(1);
-  }
-
-  void AVCC::setCompatibleProfiles(uint32_t newCompatibleProfiles){
-    setInt8(newCompatibleProfiles, 2);
-  }
-
-  uint32_t AVCC::getCompatibleProfiles(){
-    return getInt8(2);
-  }
-
-  void AVCC::setLevel(uint32_t newLevel){
-    setInt8(newLevel, 3);
-  }
-
-  uint32_t AVCC::getLevel(){
-    return getInt8(3);
-  }
-
-  void AVCC::setSPSNumber(uint32_t newSPSNumber){
-    setInt8(newSPSNumber, 5);
-  }
-
-  uint32_t AVCC::getSPSNumber(){
-    return getInt8(5);
-  }
-
-  void AVCC::setSPS(std::string newSPS){
-    setInt16(newSPS.size(), 6);
-    for (unsigned int i = 0; i < newSPS.size(); i++){
-      setInt8(newSPS[i], 8 + i);
-    } //not null-terminated
-  }
-
-  uint32_t AVCC::getSPSLen(){
-    return getInt16(6);
-  }
-
-  char* AVCC::getSPS(){
-    return payload() + 8;
-  }
-
-  void AVCC::setPPSNumber(uint32_t newPPSNumber){
-    int offset = 8 + getSPSLen();
-    setInt8(newPPSNumber, offset);
-  }
-
-  uint32_t AVCC::getPPSNumber(){
-    int offset = 8 + getSPSLen();
-    return getInt8(offset);
-  }
-
-  void AVCC::setPPS(std::string newPPS){
-    int offset = 8 + getSPSLen() + 1;
-    setInt16(newPPS.size(), offset);
-    for (unsigned int i = 0; i < newPPS.size(); i++){
-      setInt8(newPPS[i], offset + 2 + i);
-    } //not null-terminated
-  }
-
-  uint32_t AVCC::getPPSLen(){
-    int offset = 8 + getSPSLen() + 1;
-    return getInt16(offset);
-  }
-
-  char* AVCC::getPPS(){
-    int offset = 8 + getSPSLen() + 3;
-    return payload() + offset;
-  }
-
-  std::string AVCC::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[avcC] H.264 Init Data (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "Profile: " << getProfile() << std::endl;
-    r << std::string(indent + 1, ' ') << "Compatible Profiles: " << getCompatibleProfiles() << std::endl;
-    r << std::string(indent + 1, ' ') << "Level: " << getLevel() << std::endl;
-    r << std::string(indent + 1, ' ') << "SPS Number: " << getSPSNumber() << std::endl;
-    r << std::string(indent + 2, ' ') << getSPSLen() << " of SPS data" << std::endl;
-    r << std::string(indent + 1, ' ') << "PPS Number: " << getPPSNumber() << std::endl;
-    r << std::string(indent + 2, ' ') << getPPSLen() << " of PPS data" << std::endl;
-    return r.str();
-  }
-
-  std::string AVCC::asAnnexB(){
-    std::stringstream r;
-    r << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01;
-    r.write(getSPS(), getSPSLen());
-    r << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01;
-    r.write(getPPS(), getPPSLen());
-    return r.str();
-  }
-
-  void AVCC::fromAnnexB(std::string annexBFormatted){
-    ///\todo fix correct data :p
-    setVersion(0x01);
-    setProfile(0x4D);
-    setCompatibleProfiles(0x40);
-    setLevel(0x1F);
-    setSPSNumber(0xE1);
-    static char annexBHeader[] = {0x00,0x00,0x00,0x01};
-    if (memcmp(annexBFormatted.c_str(), annexBHeader, 4)){
-      return;
-    }
-    annexBFormatted.erase(0,4);
-    int separator = annexBFormatted.find(annexBHeader, 0, 4);
-    setSPS(annexBFormatted.substr(0,separator));
-    setPPSNumber(0x01);
-    annexBFormatted.erase(0,separator+4);
-    setPPS(annexBFormatted);
-  }
-
-  void AVCC::setPayload(std::string newPayload){
-    if ( !reserve(0, payloadSize(), newPayload.size())){
-      DEBUG_MSG(DLVL_ERROR, "Cannot allocate enough memory for payload");
-      return;
-    }
-    memcpy((char*)payload(), (char*)newPayload.c_str(), newPayload.size());
-  }
-  
-  //fullbox, start at 4
-  ESDS::ESDS(){
-    memcpy(data + 4, "esds", 4);
-    setESDescriptorType(0x03);
-    setExtendedESDescriptorType(0x808080);
-    setStreamPriority(16);
-    setDecoderConfigDescriptorTag(0x04);
-    setExtendedDecoderConfigDescriptorTag(0x808080);
-    setReservedFlag(true);
-    setDecoderDescriptorTypeTag(0x05);
-    setExtendedDecoderDescriptorTypeTag(0x808080);
-    setSLConfigDescriptorTypeTag(0x06);
-    setSLConfigExtendedDescriptorTypeTag(0x808010);
-    setSLValue(0x02);
-  }
-  
-  char ESDS::getESDescriptorType(){
-    return getInt8(4);
-  }
-  
-  void ESDS::setESDescriptorType(char newVal){
-    setInt8(newVal,4);
-  }
-  
-  uint32_t ESDS::getExtendedESDescriptorType(){
-    return getInt24(5);
-  }
-  //3 bytes
-  void ESDS::setExtendedESDescriptorType(uint32_t newVal){
-    setInt24(newVal,5);
-  }
-  //3 bytes
-  char ESDS::getESDescriptorTypeLength(){
-    return getInt8(8);  
-  }
-  
-  void ESDS::setESDescriptorTypeLength(char newVal){
-    setInt8(newVal,8);
-  }
-  //ESID 2 bytes
-  uint16_t ESDS::getESID(){
-    return getInt16(9);
-  }
-  
-  void ESDS::setESID(uint16_t newVal){
-    setInt16(newVal, 9);
-  }
-  
-  //stream priority 1 byte
-  char ESDS::getStreamPriority(){
-    return getInt8(11);
-  }
-  
-  void ESDS::setStreamPriority(char newVal){
-    setInt8(newVal, 11);
-  }
-  
-  //decoder config descriptor tag 1byte
-  char ESDS::getDecoderConfigDescriptorTag(){
-    return getInt8(12);
-  }
-  
-  void ESDS::setDecoderConfigDescriptorTag(char newVal){
-    setInt8(newVal, 12);
-  }
-  
-  //extended decoder config descriptor tag 3 bytes
-  uint32_t ESDS::getExtendedDecoderConfigDescriptorTag(){
-    return getInt24(13);
-  }
-  //3 bytes
-  void ESDS::setExtendedDecoderConfigDescriptorTag(uint32_t newVal){
-    setInt24(newVal, 13);
-  }
-  //3 bytes
-  //decoder config descriptor type length
-  char ESDS::getDecoderConfigDescriptorTypeLength(){
-    return getInt8(16);
-  }
-  
-  void ESDS::setDecoderConfigDescriptorTypeLength(char newVal){
-    setInt8(newVal, 16);
-  }
-  //Note: tel 8 bytes op bij de volgende functies
-  char ESDS::getByteObjectTypeID(){
-    return getInt8(17);  
-  }
-  
-  void ESDS::setByteObjectTypeID(char newVal){
-    setInt8(newVal,17);
-  }
-  
-  char ESDS::getStreamType(){
-    return getInt8(18) >> 2;  
-  }
-  //6 bits
-  void ESDS::setStreamType(char newVal){
-    setInt8(((newVal << 2) & 0xFC) + (getInt8(18) & 0x03), 18);
-  }
-  //6 bits
-  bool ESDS::getUpstreamFlag(){
-    return (((getInt8(18) >> 1) & 0x01) == 1);  
-  }
-  
-  void ESDS::setUpstreamFlag(bool newVal){
-    setInt8((getStreamType()<<2) + ((uint8_t)newVal << 1) + (uint8_t)getReservedFlag() , 18);
-  }
-  
-  bool ESDS::getReservedFlag(){
-    return ((getInt8(18) & 0x01) == 1);  
-  }
-  
-  void ESDS::setReservedFlag(bool newVal){
-    setInt8((getInt8(18) & 0xFE) + (int)newVal, 18);
-  }
-  
-  uint32_t ESDS::getBufferSize(){
-    return getInt24(19);  
-  }
-  //3 bytes
-  void ESDS::setBufferSize(uint32_t newVal){
-    setInt24(newVal,19);
-  }
-  //3 bytes
-  uint32_t ESDS::getMaximumBitRate(){
-    return getInt32(22);  
-  }
-  
-  void ESDS::setMaximumBitRate(uint32_t newVal){
-    setInt32(newVal,22);
-  }
-  
-  uint32_t ESDS::getAverageBitRate(){
-    return getInt32(26);  
-  }
-  
-  void ESDS::setAverageBitRate(uint32_t newVal){
-    setInt32(newVal,26);
-  }
-  
-  char ESDS::getDecoderDescriptorTypeTag(){
-    return getInt8(30);
-  }
-  
-  void ESDS::setDecoderDescriptorTypeTag(char newVal){
-    setInt8(newVal,30);
-  }
-  
-  uint32_t ESDS::getExtendedDecoderDescriptorTypeTag(){
-    return getInt24(31);
-  }
-  
-  //3 bytes
-  void ESDS::setExtendedDecoderDescriptorTypeTag(uint32_t newVal){
-    setInt24(newVal, 31);
-  }
-
-  //3 bytes
-  char ESDS::getConfigDescriptorTypeLength(){
-    return getInt8(34);
-  }
-  
-  void ESDS::setConfigDescriptorTypeLength(char newVal){
-    setInt8(newVal, 34);
-  }
-  
-  std::string ESDS::getESHeaderStartCodes(){
-    std::string result;
-    for (int i = 0; i < getInt8(34); i++){
-      result += getInt8(35 + i);
-    }
-    return result;
-  }
-  
-  void ESDS::setESHeaderStartCodes(std::string newVal){
-    setConfigDescriptorTypeLength(newVal.size());
-    for (unsigned int i = 0; i < newVal.size(); i++){
-      setInt8(newVal[i],35+i);
-    }
-  }
-  
-  char ESDS::getSLConfigDescriptorTypeTag(){
-    return getInt8(35 + getInt8(34));  
-  }
-  
-  void ESDS::setSLConfigDescriptorTypeTag(char newVal){
-    setInt8(newVal, 35 + getInt8(34));
-  }
-  
-  uint32_t ESDS::getSLConfigExtendedDescriptorTypeTag(){
-    return getInt24(36 + getInt8(34));  
-  }
-  //3 bytes
-  void ESDS::setSLConfigExtendedDescriptorTypeTag(uint32_t newVal){
-    setInt24(newVal, 36 + getInt8(34));
-  }
-  //3 bytes
-  char ESDS::getSLDescriptorTypeLength(){
-    return getInt8(39 + getInt8(34));
-  }
-  
-  void ESDS::setSLDescriptorTypeLength(char newVal){
-    setInt8(newVal, 39 + getInt8(34));
-  }
-  
-  char ESDS::getSLValue(){
-    return getInt8(40 + getInt8(34));
-  }
-  
-  void ESDS::setSLValue(char newVal){
-    setInt8(newVal, 40 + getInt8(34));
-  }
-  
-  std::string ESDS::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[esds] ES Descriptor Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "ESDescriptorType: 0x" << std::hex << (int)getESDescriptorType() << std::dec << std::endl;    
-    r << std::string(indent + 1, ' ') << "ExtendedESDescriptorType: 0x" << std::hex << (int)getExtendedESDescriptorType() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "ESDescriptorTypeLength:"  << (int)getESDescriptorTypeLength() << std::endl;
-    r << std::string(indent + 1, ' ') << "ESID: 0x" << std::hex << (int)getESID() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "StreamPriority: 0x" << std::hex << (int)getStreamPriority() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "DecoderConfigDescriptorTag: 0x" << std::hex << (int)getDecoderConfigDescriptorTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "ExtendedDecoderConfigDescriptorTag: 0x" << std::hex << (int)getExtendedDecoderConfigDescriptorTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "DecoderConfigDescriptorTypeLength: " << (int)getDecoderConfigDescriptorTypeLength() << std::endl;
-    r << std::string(indent + 1, ' ') << "ByteObjectTypeID: 0x" << std::hex << (int)getByteObjectTypeID() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "StreamType: 0x" << std::hex << (int)getStreamType() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "UpstreamFlag: 0x" << std::hex << (int)getUpstreamFlag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "BufferSize: 0x" << std::hex << (int)getBufferSize() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "MaximumBitRate: 0x" << std::hex << (int)getMaximumBitRate() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "AverageBitRate: 0x" << std::hex << (int)getAverageBitRate() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "DecoderDescriptorTypeTag: 0x" << std::hex << (int)getDecoderDescriptorTypeTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "ExtendedDecoderDescriptorTypeTag: 0x" << std::hex << (int)getExtendedDecoderDescriptorTypeTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "ConfigDescriptorTypeLength: 0x" << std::hex << (int)getConfigDescriptorTypeLength() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "ESHeaderStartCodes: 0x";
-    for (unsigned int i = 0; i<getESHeaderStartCodes().size(); i++){
-      r << std::hex << std::setw(2) << std::setfill('0') << (int)getESHeaderStartCodes()[i] << std::dec;
-    }
-    r << std::endl;
-    r << std::string(indent + 1, ' ') << "SLConfigDescriptorTypeTag: 0x" << std::hex << (int)getSLConfigDescriptorTypeTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "SLConfigExtendedDescriptorTypeTag: 0x" << std::hex << (int)getSLConfigExtendedDescriptorTypeTag() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "SLDescriptorTypeLength: 0x" << std::hex << (int)getSLDescriptorTypeLength() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "SLValue: 0x" << std::hex << (int)getSLValue() << std::dec << std::endl;
-    return r.str();
-  }
-  
-  SDTP::SDTP(){
-    memcpy(data + 4, "sdtp", 4);
-  }
-
-  void SDTP::setVersion(uint32_t newVersion){
-    setInt8(newVersion, 0);
-  }
-
-  uint32_t SDTP::getVersion(){
-    return getInt8(0);
-  }
-
-  void SDTP::setValue(uint32_t newValue, size_t index){
-    setInt8(newValue, index);
-  }
-
-  uint32_t SDTP::getValue(size_t index){
-    return getInt8(index);
-  }
-
-  std::string SDTP::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[sdtp] Sample Dependancy Type (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Samples: " << (boxedSize() - 12) << std::endl;
-    for (size_t i = 1; i <= boxedSize() - 12; ++i){
-      uint32_t val = getValue(i+3);
-      r << std::string(indent + 2, ' ') << "[" << i << "] = ";
-      switch (val & 3){
-        case 0:
-          r << "               ";
-          break;
-        case 1:
-          r << "Redundant,     ";
-          break;
-        case 2:
-          r << "Not redundant, ";
-          break;
-        case 3:
-          r << "Error,         ";
-          break;
-      }
-      switch (val & 12){
-        case 0:
-          r << "                ";
-          break;
-        case 4:
-          r << "Not disposable, ";
-          break;
-        case 8:
-          r << "Disposable,     ";
-          break;
-        case 12:
-          r << "Error,          ";
-          break;
-      }
-      switch (val & 48){
-        case 0:
-          r << "            ";
-          break;
-        case 16:
-          r << "IFrame,     ";
-          break;
-        case 32:
-          r << "Not IFrame, ";
-          break;
-        case 48:
-          r << "Error,      ";
-          break;
-      }
-      r << "(" << val << ")" << std::endl;
-    }
-    return r.str();
-  }
-  
-  FTYP::FTYP(){
-    memcpy(data + 4, "ftyp", 4);
-    setMajorBrand(0);
-    setMinorVersion(0);
-  }
-  
-  void FTYP::setMajorBrand(uint32_t newMajorBrand){
-    setInt32(newMajorBrand, 0);
-  }
-  
-  uint32_t FTYP::getMajorBrand(){
-    return getInt32(0);
-  }
-  
-  void FTYP::setMinorVersion(uint32_t newMinorVersion){
-    setInt32(newMinorVersion, 4);
-  }
-  
-  uint32_t FTYP::getMinorVersion(){
-    return getInt32(4);
-  }
-  
-  uint32_t FTYP::getCompatibleBrandsCount(){
-    return (payloadSize() - 8) / 4;
-  }
-  
-  void FTYP::setCompatibleBrands(uint32_t newCompatibleBrand, size_t index){
-    setInt32(newCompatibleBrand, 8 + (index * 4));
-  }
-  
-  uint32_t FTYP::getCompatibleBrands(size_t index){
-    if (index >= getCompatibleBrandsCount()){
-      return 0;
-    }
-    return getInt32(8 + (index * 4));
-  }
-  
-  std::string FTYP::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[ftyp] File Type (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "MajorBrand: 0x" << std::hex << getMajorBrand() << std::dec << std::endl;
-    r << std::string(indent + 1, ' ') << "MinorVersion: " << getMinorVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl;
-    for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++){
-      r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: 0x" << std::hex << getCompatibleBrands(i) << std::dec << std::endl;
-    }
-    return r.str();
-  }
-  
-  MOOV::MOOV(){
-    memcpy(data + 4, "moov", 4);
-  }
-  
-  std::string MOOV::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[moov] Movie Box"));
-  }
-  
-  MVEX::MVEX(){
-    memcpy(data + 4, "mvex", 4);
-  }
-  
-  std::string MVEX::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[mvex] Movie Extends Header Box"));
-  }
-  
-  TREX::TREX(){
-    memcpy(data + 4, "trex", 4);
-  }
-  
-  void TREX::setTrackID(uint32_t newTrackID){
-    setInt32(newTrackID, 0);
-  }
-  
-  uint32_t TREX::getTrackID(){
-    return getInt32(0);
-  }
-  
-  void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex){
-    setInt32(newDefaultSampleDescriptionIndex,4);
-  }
-  
-  uint32_t TREX::getDefaultSampleDescriptionIndex(){
-    return getInt32(4);
-  }
-  
-  void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration){
-    setInt32(newDefaultSampleDuration,8);
-  }
-  
-  uint32_t TREX::getDefaultSampleDuration(){
-    return getInt32(8);
-  }
-  
-  void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize){
-    setInt32(newDefaultSampleSize,12);
-  }
-  
-  uint32_t TREX::getDefaultSampleSize(){
-    return getInt32(12);
-  }
-  
-  void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags){
-    setInt32(newDefaultSampleFlags,16);
-  }
-  
-  uint32_t TREX::getDefaultSampleFlags(){
-    return getInt32(16);
-  }
-  
-  std::string TREX::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[trex] Track Extends (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
-    r << std::string(indent + 1, ' ') << "DefaultSampleDescriptionIndex : " << getDefaultSampleDescriptionIndex() << std::endl;
-    r << std::string(indent + 1, ' ') << "DefaultSampleDuration : " << getDefaultSampleDuration() << std::endl;
-    r << std::string(indent + 1, ' ') << "DefaultSampleSize : " << getDefaultSampleSize() << std::endl;
-    r << std::string(indent + 1, ' ') << "DefaultSampleFlags : " << getDefaultSampleFlags() << std::endl;
-    return r.str();
-  }
-
-  TRAK::TRAK(){
-    memcpy(data + 4, "trak", 4);
-  }
-  
-  std::string TRAK::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[trak] Track Structure"));
-  }
-
-  MDIA::MDIA(){
-    memcpy(data + 4, "mdia", 4);
-  }
-  
-  std::string MDIA::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[mdia] Track Media Structure"));
-  }
-
-  MINF::MINF(){
-    memcpy(data + 4, "minf", 4);
-  }
-  
-  std::string MINF::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[minf] Media Information"));
-  }
-
-  DINF::DINF(){
-    memcpy(data + 4, "dinf", 4);
-  }
-  
-  std::string DINF::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[dinf] Data Information"));
-  }
-
-  MFRA::MFRA(){
-    memcpy(data + 4, "mfra", 4);
-  }
-  
-  std::string MFRA::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[mfra] Movie Fragment Random Acces Box"));
-  }
-  
-  MFRO::MFRO(){
-    memcpy(data + 4, "mfro", 4);
-  }
-
-  void MFRO::setSize(uint32_t newSize){
-    setInt32(newSize,0);
-  }
-  
-  uint32_t MFRO::getSize(){
-    return getInt32(0);
-  }
-  
-  std::string MFRO::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[mfro] Movie Fragment Random Access Offset (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Size: " << getSize() << std::endl;
-    return r.str();
-  }
-  
-  HDLR::HDLR(){
-    memcpy(data + 4, "hdlr", 4);
-    setName("");
-  }
-  
-  void HDLR::setSize(uint32_t newSize){
-    setInt32(newSize,0);
-  }
-  
-  uint32_t HDLR::getSize(){
-    return getInt32(0);
-  }
-  
-  void HDLR::setPreDefined(uint32_t newPreDefined){
-    setInt32(newPreDefined,4);
-  }
-  
-  uint32_t HDLR::getPreDefined(){
-    return getInt32(4);
-  }
-  
-  void HDLR::setHandlerType(uint32_t newHandlerType){
-    setInt32(newHandlerType, 8);
-  }
-  
-  uint32_t HDLR::getHandlerType(){
-    return getInt32(8);
-  }
-  
-  void HDLR::setName(std::string newName){
-    setString(newName, 24);
-  }
-  
-  std::string HDLR::getName(){
-    return getString(24);
-  }
-  
-  std::string HDLR::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[hdlr] Handler Reference (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl;
-    r << std::string(indent + 1, ' ') << "HandlerType: " << 
-      (char)((getHandlerType() & 0xFF000000) >> 24) << (char)((getHandlerType() & 0x00FF0000) >> 16) <<
-      (char)((getHandlerType() & 0x0000FF00) >> 8) << (char)(getHandlerType() & 0x000000FF) << std::endl;
-    r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl;
-    return r.str();
-  }
-  
-  //Note: next 4 headers inherit from fullBox, start at byte 4.
-  VMHD::VMHD(){
-    memcpy(data + 4, "vmhd", 4);
-    setGraphicsMode(0);
-    setOpColor(0,0);
-    setOpColor(0,1);
-    setOpColor(0,2);
-  }
-  
-  void VMHD::setGraphicsMode(uint16_t newGraphicsMode){
-    setInt16(newGraphicsMode,4);
-  }
-  
-  uint16_t VMHD::getGraphicsMode(){
-    return getInt16(4);
-  }
-  
-  uint32_t VMHD::getOpColorCount(){
-    return 3;
-  }
-  
-  void VMHD::setOpColor(uint16_t newOpColor, size_t index){
-    if (index <3){
-      setInt16(newOpColor, 6 + (2 * index));
-    }
-  }
-  
-  uint16_t VMHD::getOpColor(size_t index){
-    if (index < 3){
-      return getInt16(6 + (index * 2));
-    }else{
-      return 0;
-    }
-  }
-  
-  std::string VMHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[vmhd] Video Media Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "GraphicsMode: " << getGraphicsMode() << std::endl;
-    for (unsigned int i = 0; i < getOpColorCount(); i++){
-      r << std::string(indent + 1, ' ') << "OpColor["<<i<<"]: " << getOpColor(i) << std::endl;
-    }
-    return r.str();
-  }
-    
-  SMHD::SMHD(){
-    memcpy(data + 4, "smhd", 4);
-    setBalance(0);
-    setInt16(0,6);
-  }
-  
-  void SMHD::setBalance(int16_t newBalance){
-    setInt16(newBalance,4);
-  }
-  
-  int16_t SMHD::getBalance(){
-    return getInt16(4);
-  }
-  
-  std::string SMHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[smhd] Sound Media Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "Balance: " << getBalance() << std::endl;
-    return r.str();
-  }
-
-  HMHD::HMHD(){
-    memcpy(data + 4, "hmhd", 4);
-  }
-  
-  void HMHD::setMaxPDUSize(uint16_t newMaxPDUSize){
-    setInt16(newMaxPDUSize,4);
-  }
-  
-  uint16_t HMHD::getMaxPDUSize(){
-    return getInt16(4);
-  }
-  
-  void HMHD::setAvgPDUSize(uint16_t newAvgPDUSize){
-    setInt16(newAvgPDUSize,6);
-  }
-  
-  uint16_t HMHD::getAvgPDUSize(){
-    return getInt16(6);
-  }
-  
-  void HMHD::setMaxBitRate(uint32_t newMaxBitRate){
-    setInt32(newMaxBitRate,8);
-  }
-  
-  uint32_t HMHD::getMaxBitRate(){
-    return getInt32(8);
-  }
-  
-  void HMHD::setAvgBitRate(uint32_t newAvgBitRate){
-    setInt32(newAvgBitRate,12);
-  }
-  
-  uint32_t HMHD::getAvgBitRate(){
-    return getInt32(12);
-  }
-  
-  std::string HMHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[hmhd] Hint Media Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "maxPDUSize: " << getMaxPDUSize() << std::endl;
-    r << std::string(indent + 1, ' ') << "avgPDUSize: " << getAvgPDUSize() << std::endl;
-    r << std::string(indent + 1, ' ') << "maxBitRate: " << getMaxBitRate() << std::endl;
-    r << std::string(indent + 1, ' ') << "avgBitRate: " << getAvgBitRate() << std::endl;
-    return r.str();
-  }
-  
-  NMHD::NMHD(){
-    memcpy(data + 4, "nmhd", 4);
-  }
-  
-  std::string NMHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[nmhd] Null Media Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    return r.str();
-  }
-  
-  MEHD::MEHD(){
-    memcpy(data + 4, "mehd", 4);
-  }
-  
-  void MEHD::setFragmentDuration(uint64_t newFragmentDuration){
-    if (getVersion() == 0){
-      setInt32(newFragmentDuration,4);
-    }else{
-      setInt64(newFragmentDuration,4);
-    }
-  }
-  
-  uint64_t MEHD::getFragmentDuration(){
-    if(getVersion() == 0){
-      return getInt32(4);
-    }else{
-      return getInt64(4);
-    }
-  }
-  
-  std::string MEHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[mehd] Movie Extends Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "FragmentDuration: " << getFragmentDuration() << std::endl;
-    return r.str();
-  }
-  
-  STBL::STBL(){
-    memcpy(data + 4, "stbl", 4);
-  }
-  
-  std::string STBL::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[stbl] Sample Table"));
-  }
-  
-  URL::URL(){
-    memcpy(data + 4, "url ", 4);
-  }
-  
-  void URL::setLocation(std::string newLocation){
-    setString(newLocation, 4);
-  }
-  
-  std::string URL::getLocation(){
-    return std::string(getString(4),getStringLen(4));
-  }
-  
-  std::string URL::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[url ] URL Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "Location: " << getLocation() << std::endl;
-    return r.str();
-  }
-  
-
-  URN::URN(){
-    memcpy(data + 4, "urn ", 4);
-  }
-  
-  void URN::setName(std::string newName){
-    setString(newName, 4);
-  }
-  
-  std::string URN::getName(){
-    return std::string(getString(4),getStringLen(4));
-  }
-  
-  void URN::setLocation(std::string newLocation){
-    setString(newLocation, 4 + getStringLen(4) + 1);
-  }
-  
-  std::string URN::getLocation(){
-    int loc = 4 + getStringLen(4) + 1;
-    return std::string(getString(loc),getStringLen(loc));
-  }
-  
-  std::string URN::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[urn ] URN Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl;
-    r << std::string(indent + 1, ' ') << "Location: " << getLocation() << std::endl;
-    return r.str();
-  }
-  
-
-  DREF::DREF(char v, uint32_t f){
-    memcpy(data + 4, "dref", 4);
-    setVersion(v);
-    setFlags(f);
-    setInt32(0,4);
-  }
-  
-  uint32_t DREF::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void DREF::setDataEntry(fullBox & newDataEntry, size_t index){
-    unsigned int i;
-    uint32_t offset = 8; //start of boxes
-    for (i=0; i< getEntryCount() && i < index; i++){
-      offset += getBoxLen(offset);
-    }
-    if (index+1 > getEntryCount()){
-      int amount = index + 1 - getEntryCount();
-      if ( !reserve(payloadOffset + offset, 0, amount * 8)){
-        return;
-      }
-      for (int j = 0; j < amount; ++j){
-        memcpy(data + payloadOffset + offset + j * 8, "\000\000\000\010erro", 8);
-      }
-      setInt32(index + 1, 4);
-      offset += (index - i) * 8;
-    }
-    setBox(newDataEntry, offset);
-  }
-  
-  Box & DREF::getDataEntry(size_t index){
-    uint32_t offset = 8;
-    if (index > getEntryCount()){
-      static Box res;
-      return (Box &)res;
-    }
-    
-    for (unsigned int i=0; i < index; i++){
-      offset += getBoxLen(offset);
-    }
-    return (Box &)getBox(offset);
-  }
-  
-  std::string DREF::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[dref] Data Reference Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i< getEntryCount(); i++){
-      r << getDataEntry(i).toPrettyString(indent+1);
-    }
-    return r.str();
-  }
-  
-  MVHD::MVHD(char v, uint32_t f){
-    memcpy(data + 4, "mvhd", 4);
-    setVersion(v);
-    setFlags(f);
-    setCreationTime(0);
-    setModificationTime(0);
-    setTimeScale(1000);
-    setDuration(0);
-    setRate(0x00010000);
-    setVolume(0x0100);
-    setMatrix(0x40000000,0);
-    setMatrix(0x00010000,4);
-    setMatrix(0x00010000,8);
-    setTrackID(1);
-  }
-  
-  void MVHD::setCreationTime(uint64_t newCreationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newCreationTime, 4);
-    }else{
-      setInt64(newCreationTime, 4);
-    }
-  }
-  
-  uint64_t MVHD::getCreationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(4);
-    }else{
-      return getInt64(4);
-    }
-  }
-  
-  void MVHD::setModificationTime(uint64_t newModificationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newModificationTime, 8);
-    }else{
-      setInt64(newModificationTime, 12);
-    }
-  }
-  
-  uint64_t MVHD::getModificationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(8);
-    }else{
-      return getInt64(12);
-    }
-  }
-  
-  void MVHD::setTimeScale(uint32_t newTimeScale){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newTimeScale, 12);
-    }else{
-      setInt32(newTimeScale, 20);
-    }
-  }
-  
-  uint32_t MVHD::getTimeScale(){
-    if (getVersion() == 0){
-      return getInt32(12);
-    }else{
-      return getInt32(20);
-    }
-  }
-  
-  void MVHD::setDuration(uint64_t newDuration){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newDuration, 16);
-    }else{
-      setInt64(newDuration, 24);
-    }
-  }
-  
-  uint64_t MVHD::getDuration(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(16);
-    }else{
-      return getInt64(24);
-    }
-  }
-  
-  void MVHD::setRate(uint32_t newRate){
-    if (getVersion() == 0){
-      setInt32( newRate, 20);
-    }else{
-      setInt32(newRate, 32);
-    }
-  }
-  
-  uint32_t MVHD::getRate(){
-    if (getVersion() == 0){
-      return getInt32(20);
-    }else{
-      return getInt32(32);
-    }
-  }
-  
-  void MVHD::setVolume(uint16_t newVolume){
-    if (getVersion() == 0){
-      setInt16(newVolume, 24);
-    }else{
-      setInt16(newVolume, 36);
-    }
-  }
-  
-  uint16_t MVHD::getVolume(){
-    if (getVersion() == 0){
-      return getInt16(24);
-    }else{
-      return getInt16(36);
-    }
-  }
-  //10 bytes reserverd in between
-  uint32_t MVHD::getMatrixCount(){
-    return 9;
-  }
-  
-  void MVHD::setMatrix(int32_t newMatrix, size_t index){
-    int offset = 0;
-    if (getVersion() == 0){
-      offset = 24 + 2 + 10;
-    }else{
-      offset = 36 + 2 + 10;
-    }
-    setInt32(newMatrix, offset + index * 4);
-  }
-  
-  int32_t MVHD::getMatrix(size_t index){
-    int offset = 0;
-    if (getVersion() == 0){
-      offset = 24 + 2 + 10;
-    }else{
-      offset = 36 + 2 + 10;
-    }
-    return getInt32(offset + index * 4);
-  }
-  
-  //24 bytes of pre-defined in between
-  void MVHD::setTrackID(uint32_t newTrackID){
-    if (getVersion() == 0){
-      setInt32(newTrackID, 86);
-    }else{
-      setInt32(newTrackID, 98);
-    }
-  }
-  
-  uint32_t MVHD::getTrackID(){
-    if (getVersion() == 0){
-      return getInt32(86);
-    }else{
-      return getInt32(98);
-    }
-  }
-  
-  std::string MVHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[mvhd] Movie Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl;
-    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
-    r << std::string(indent + 1, ' ') << "Rate: " << getRate() << std::endl;
-    r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl;
-    r << std::string(indent + 1, ' ') << "Matrix: ";
-    for (unsigned int i = 0; i< getMatrixCount(); i++){
-      r << getMatrix(i);
-      if (i!=getMatrixCount()-1){
-        r << ", ";
-      }
-    }
-    r << std::endl;
-    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
-    return r.str();
-  }
-  
-  TFRA::TFRA(){
-    memcpy(data + 4, "dref", 4);
-  }
-  
-  //note, fullbox starts at byte 4
-  void TFRA::setTrackID(uint32_t newTrackID){
-    setInt32(newTrackID, 4);
-  }
-  
-  uint32_t TFRA::getTrackID(){
-    return getInt32(4);
-  }
-  
-  void TFRA::setLengthSizeOfTrafNum(char newVal){
-    char part = getInt8(11);
-    setInt8(((newVal & 0x03)<<4) + (part & 0xCF),11);
-  }
-  
-  char TFRA::getLengthSizeOfTrafNum(){
-    return (getInt8(11)>>4) & 0x03;
-  }
-  
-  void TFRA::setLengthSizeOfTrunNum(char newVal){
-    char part = getInt8(11);
-    setInt8(((newVal & 0x03)<<2) + (part & 0xF3),11);
-  }
-  
-  char TFRA::getLengthSizeOfTrunNum(){
-    return (getInt8(11)>>2) & 0x03;
-  }
-  
-  void TFRA::setLengthSizeOfSampleNum(char newVal){
-    char part = getInt8(11);
-    setInt8(((newVal & 0x03)) + (part & 0xFC),11);
-  }
-  
-  char TFRA::getLengthSizeOfSampleNum(){
-    return (getInt8(11)) & 0x03;
-  }
-  
-  void TFRA::setNumberOfEntry(uint32_t newNumberOfEntry){
-    setInt32(newNumberOfEntry,12);
-  }
-  
-  uint32_t TFRA::getNumberOfEntry(){
-    return getInt32(12);
-  }
-  
-  uint32_t TFRA::getTFRAEntrySize(){
-    int EntrySize= (getVersion()==1 ? 16 : 8);
-    EntrySize += getLengthSizeOfTrafNum()+1;
-    EntrySize += getLengthSizeOfTrunNum()+1;
-    EntrySize += getLengthSizeOfSampleNum()+1;
-    return EntrySize;
-  }
-  
-  void TFRA::setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no){
-    if (no + 1 > getNumberOfEntry()){//if a new entry is issued
-      uint32_t offset = 16 + getTFRAEntrySize() * getNumberOfEntry();//start of filler in bytes
-      uint32_t fillsize = (no + 1 - getNumberOfEntry())*getTFRAEntrySize();//filler in bytes
-      if ( !reserve(offset, 0, fillsize)){//filling space
-        return;
-      }
-      setNumberOfEntry(no+1);
-    }
-    uint32_t loc = 16 + no * getTFRAEntrySize();
-    if (getVersion() == 1){
-      setInt64(newTFRAEntry.time, loc);
-      setInt64(newTFRAEntry.moofOffset, loc+8);
-      loc += 16;
-    }else{
-      setInt32(newTFRAEntry.time, loc);
-      setInt32(newTFRAEntry.moofOffset, loc+4);
-      loc += 8;
-    }
-    switch (getLengthSizeOfTrafNum()){
-      case 0:
-        setInt8(newTFRAEntry.trafNumber, loc);        
-        break;
-      case 1:
-        setInt16(newTFRAEntry.trafNumber, loc);        
-        break;
-      case 2:
-        setInt24(newTFRAEntry.trafNumber, loc);        
-        break;
-      case 3:
-        setInt32(newTFRAEntry.trafNumber, loc);        
-        break;
-    }
-    loc += getLengthSizeOfTrafNum() + 1;
-    switch (getLengthSizeOfTrunNum()){
-      case 0:
-        setInt8(newTFRAEntry.trunNumber, loc);        
-        break;
-      case 1:
-        setInt16(newTFRAEntry.trunNumber, loc);        
-        break;
-      case 2:
-        setInt24(newTFRAEntry.trunNumber, loc);        
-        break;
-      case 3:
-        setInt32(newTFRAEntry.trunNumber, loc);        
-        break;
-    }
-    loc += getLengthSizeOfTrunNum() + 1;
-    switch (getLengthSizeOfSampleNum()){
-      case 0:
-        setInt8(newTFRAEntry.sampleNumber, loc);        
-        break;
-      case 1:
-        setInt16(newTFRAEntry.sampleNumber, loc);        
-        break;
-      case 2:
-        setInt24(newTFRAEntry.sampleNumber, loc);        
-        break;
-      case 3:
-        setInt32(newTFRAEntry.sampleNumber, loc);        
-        break;
-    }
-  }
-  
-  TFRAEntry & TFRA::getTFRAEntry(uint32_t no){
-    static TFRAEntry retval;
-    if (no >= getNumberOfEntry()){
-      static TFRAEntry inval;
-      return inval;
-    }
-    uint32_t loc = 16 + no * getTFRAEntrySize();
-    if (getVersion() == 1){
-      retval.time = getInt64(loc);
-      retval.moofOffset = getInt64(loc + 8);
-      loc += 16;
-    }else{
-      retval.time = getInt32(loc);
-      retval.moofOffset = getInt32(loc + 4);
-      loc += 8;
-    }
-    switch (getLengthSizeOfTrafNum()){
-      case 0:
-        retval.trafNumber = getInt8(loc);        
-        break;
-      case 1:
-        retval.trafNumber = getInt16(loc);        
-        break;
-      case 2:
-        retval.trafNumber = getInt24(loc);        
-        break;
-      case 3:
-        retval.trafNumber = getInt32(loc);        
-        break;
-    }
-    loc += getLengthSizeOfTrafNum() + 1;
-    switch (getLengthSizeOfTrunNum()){
-      case 0:
-        retval.trunNumber = getInt8(loc);        
-        break;
-      case 1:
-        retval.trunNumber = getInt16(loc);        
-        break;
-      case 2:
-        retval.trunNumber = getInt24(loc);        
-        break;
-      case 3:
-        retval.trunNumber = getInt32(loc);        
-        break;
-    }
-    loc += getLengthSizeOfTrunNum() + 1;
-    switch (getLengthSizeOfSampleNum()){
-      case 0:
-        retval.sampleNumber = getInt8(loc);        
-        break;
-      case 1:
-        retval.sampleNumber = getInt16(loc);        
-        break;
-      case 2:
-        retval.sampleNumber = getInt24(loc);        
-        break;
-      case 3:
-        retval.sampleNumber = getInt32(loc);        
-        break;
-    }
-    return retval;
-  }
-       
-  std::string TFRA::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[tfra] Track Fragment Random Access Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
-    r << std::string(indent + 1, ' ') << "lengthSizeOfTrafNum: " << (int)getLengthSizeOfTrafNum() << std::endl;
-    r << std::string(indent + 1, ' ') << "lengthSizeOfTrunNum: " << (int)getLengthSizeOfTrunNum() << std::endl;
-    r << std::string(indent + 1, ' ') << "lengthSizeOfSampleNum: " << (int)getLengthSizeOfSampleNum() << std::endl;
-    r << std::string(indent + 1, ' ') << "NumberOfEntry: " << getNumberOfEntry() << std::endl;
-    for (unsigned int i = 0; i < getNumberOfEntry(); i++){
-      static TFRAEntry temp;
-      temp = getTFRAEntry(i);
-      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
-      r << std::string(indent + 2, ' ') << "Time: " << temp.time << std::endl;
-      r << std::string(indent + 2, ' ') << "MoofOffset: " << temp.moofOffset << std::endl;
-      r << std::string(indent + 2, ' ') << "TrafNumber: " << temp.trafNumber << std::endl;
-      r << std::string(indent + 2, ' ') << "TrunNumber: " << temp.trunNumber << std::endl;
-      r << std::string(indent + 2, ' ') << "SampleNumber: " << temp.sampleNumber << std::endl;
-    }
-    return r.str();
-  }
-
-  TKHD::TKHD(char v, uint32_t f){
-    memcpy(data + 4, "tkhd", 4);
-    setVersion(v);
-    setFlags(f);
-    setCreationTime(0);
-    setModificationTime(0);
-    setTrackID(0);
-    setDuration(0);
-    setLayer(0);
-    setAlternateGroup(0);
-    setVolume(0x0100);
-    setMatrix(0x00010000,0);
-    setMatrix(0x00010000,4);
-    //fills automatically with zero's
-    setMatrix(0x40000000,8);
-    setWidth(0);
-    setHeight(0);
-  }
-  
-  void TKHD::setCreationTime(uint64_t newCreationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newCreationTime, 4);
-    }else{
-      setInt64(newCreationTime, 4);
-    }
-  }
-  
-  uint64_t TKHD::getCreationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(4);
-    }else{
-      return getInt64(4);
-    }
-  }
-  
-  void TKHD::setModificationTime(uint64_t newModificationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newModificationTime, 8);
-    }else{
-      setInt64(newModificationTime, 12);
-    }
-  }
-  
-  uint64_t TKHD::getModificationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(8);
-    }else{
-      return getInt64(12);
-    }
-  }
-  
-  void TKHD::setTrackID(uint32_t newTrackID){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newTrackID, 12);
-    }else{
-      setInt32(newTrackID, 20);
-    }
-  }
-  
-  uint32_t TKHD::getTrackID(){
-    if (getVersion() == 0){
-      return getInt32(12);
-    }else{
-      return getInt32(20);
-    }
-  }
-  //note 4 bytes reserved in between
-  void TKHD::setDuration(uint64_t newDuration){
-    if (getVersion() == 0){
-      setInt32(newDuration, 20);
-    }else{
-      setInt64(newDuration, 28);
-    }
-  }
-  
-  uint64_t TKHD::getDuration(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(20);
-    }else{
-      return getInt64(28);
-    }
-  }
-  //8 bytes reserved in between
-  void TKHD::setLayer(uint16_t newLayer){
-    if (getVersion() == 0){
-      setInt16(newLayer, 32);
-    }else{
-      setInt16(newLayer, 44);
-    }
-  }
-  
-  uint16_t TKHD::getLayer(){
-    if (getVersion() == 0){
-      return getInt16(32);
-    }else{
-      return getInt16(44);
-    }
-  }
-  
-  void TKHD::setAlternateGroup(uint16_t newAlternateGroup){
-    if (getVersion() == 0){
-      setInt16(newAlternateGroup, 34);
-    }else{
-      setInt16(newAlternateGroup, 46);
-    }
-  }
-  
-  uint16_t TKHD::getAlternateGroup(){
-    if (getVersion() == 0){
-      return getInt16(34);
-    }else{
-      return getInt16(46);
-    }
-  }
-  
-  void TKHD::setVolume(uint16_t newVolume){
-    if (getVersion() == 0){
-      setInt16(newVolume, 36);
-    }else{
-      setInt16(newVolume, 48);
-    }
-  }
-  
-  uint16_t TKHD::getVolume(){
-    if (getVersion() == 0){
-      return getInt16(36);
-    }else{
-      return getInt16(48);
-    }
-  }
-  //2 bytes reserved in between
-  uint32_t TKHD::getMatrixCount(){
-    return 9;
-  }
-  
-  void TKHD::setMatrix(int32_t newMatrix, size_t index){
-    int offset = 0;
-    if (getVersion() == 0){
-      offset = 36 + 2 + 2;
-    }else{
-      offset = 48 + 2 + 2;
-    }
-    setInt32(newMatrix, offset + index * 4);
-  }
-  
-  int32_t TKHD::getMatrix(size_t index){
-    int offset = 0;
-    if (getVersion() == 0){
-      offset = 36 + 2 + 2;
-    }else{
-      offset = 48 + 2 + 2;
-    }
-    return getInt32(offset + index * 4);
-  }
-  
-  void TKHD::setWidth(uint32_t newWidth){
-    if (getVersion() == 0){
-      setInt32(newWidth, 76);
-    }else{
-      setInt32(newWidth, 88);
-    }
-  }
-  
-  uint32_t TKHD::getWidth(){
-    if (getVersion() == 0){
-      return getInt32(76);
-    }else{
-      return getInt32(88);
-    }
-  }
-  
-  void TKHD::setHeight(uint32_t newHeight){
-    if (getVersion() == 0){
-      setInt32(newHeight, 80);
-    }else{
-      setInt32(newHeight, 92);
-    }
-  }
-  
-  uint32_t TKHD::getHeight(){
-    if (getVersion() == 0){
-      return getInt32(80);
-    }else{
-      return getInt32(92);
-    }
-  }
-        
-  std::string TKHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[tkhd] Track Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
-    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
-    r << std::string(indent + 1, ' ') << "Layer: " << getLayer() << std::endl;
-    r << std::string(indent + 1, ' ') << "AlternateGroup: " << getAlternateGroup() << std::endl;
-    r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl;
-    r << std::string(indent + 1, ' ') << "Matrix: ";
-    for (unsigned int i = 0; i< getMatrixCount(); i++){
-      r << getMatrix(i);
-      if (i!=getMatrixCount()-1){
-        r << ", ";
-      }
-    }
-    r << std::endl;
-    r << std::string(indent + 1, ' ') << "Width: " << (getWidth() >> 16) << "." << (getWidth() & 0xFFFF) << std::endl;
-    r << std::string(indent + 1, ' ') << "Height: " << (getHeight() >> 16) << "." << (getHeight() & 0xFFFF) << std::endl;
-    return r.str();
-  }
-
-  MDHD::MDHD(char v, uint32_t f){
-    memcpy(data + 4, "mdhd", 4);
-    setVersion(v);
-    setFlags(f);
-    setCreationTime(0);
-    setModificationTime(0);
-    setTimeScale(1000);
-    setDuration(0);
-    setLanguage(0);
-    if (v==0){
-      setInt16(0,22);
-    }else{
-      setInt16(0,34);
-    }
-  }
-  
-  void MDHD::setCreationTime(uint64_t newCreationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newCreationTime, 4);
-    }else{
-      setInt64(newCreationTime, 4);
-    }
-  }
-  
-  uint64_t MDHD::getCreationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(4);
-    }else{
-      return getInt64(4);
-    }
-  }
-  
-  void MDHD::setModificationTime(uint64_t newModificationTime){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newModificationTime, 8);
-    }else{
-      setInt64(newModificationTime, 12);
-    }
-  }
-  
-  uint64_t MDHD::getModificationTime(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(8);
-    }else{
-      return getInt64(12);
-    }
-  }
-  
-  void MDHD::setTimeScale(uint32_t newTimeScale){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newTimeScale, 12);
-    }else{
-      setInt32(newTimeScale, 20);
-    }
-  }
-  
-  uint32_t MDHD::getTimeScale(){
-    if (getVersion() == 0){
-      return getInt32(12);
-    }else{
-      return getInt32(20);
-    }
-  }
-  
-  void MDHD::setDuration(uint64_t newDuration){
-    if (getVersion() == 0){
-      setInt32((uint32_t) newDuration, 16);
-    }else{
-      setInt64(newDuration, 24);
-    }
-  }
-  
-  uint64_t MDHD::getDuration(){
-    if (getVersion() == 0){
-      return (uint64_t)getInt32(16);
-    }else{
-      return getInt64(24);
-    }
-  }
-
-  void MDHD::setLanguage (uint16_t newLanguage){
-    if (getVersion() == 0){
-      setInt16(newLanguage & 0x7F, 20);
-    }else{
-      setInt16(newLanguage & 0x7F, 32);
-    }
-  }
-  
-  uint16_t MDHD::getLanguage(){
-    if (getVersion() == 0){
-      return getInt16(20) & 0x7F;
-    }else{
-      return getInt16(32) & 0x7F;
-    }
-  }
-  
-  std::string MDHD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[mdhd] Media Header Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl;
-    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
-    r << std::string(indent + 1, ' ') << "Language: 0x" << std::hex << getLanguage() << std::dec<< std::endl;
-    return r.str();
-  }
-  
-  STTS::STTS(char v, uint32_t f){
-    memcpy(data + 4, "stts", 4);
-    setVersion(v);
-    setFlags(f);
-    setEntryCount(0);
-  }
-  
-  void STTS::setEntryCount(uint32_t newEntryCount){
-    setInt32(newEntryCount, 4);
-  }
-  
-  uint32_t STTS::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void STTS::setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no){
-    if(no + 1 > getEntryCount()){
-      setEntryCount(no + 1);
-      for (unsigned int i = getEntryCount(); i < no; i++){
-        setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits
-      }
-    }
-    setInt32(newSTTSEntry.sampleCount, 8 + no * 8);
-    setInt32(newSTTSEntry.sampleDelta, 8 + (no * 8) + 4);
-  }
-  
-  STTSEntry STTS::getSTTSEntry(uint32_t no){
-    static STTSEntry retval;
-    if (no >= getEntryCount()){
-      static STTSEntry inval;
-      return inval;
-    }
-    retval.sampleCount = getInt32(8 + (no * 8));
-    retval.sampleDelta = getInt32(8 + (no * 8) + 4);
-    return retval;
-  }
-  
-  std::string STTS::toPrettyString(uint32_t indent){
-      std::stringstream r;
-    r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      static STTSEntry temp;
-      temp = getSTTSEntry(i);
-      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
-      r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl;
-      r << std::string(indent + 2, ' ') << "SampleDelta: " << temp.sampleDelta << std::endl;
-    }
-    return r.str();
-
-  }
-  
-  CTTS::CTTS(){
-    memcpy(data + 4, "ctts", 4);
-  }
-  
-  void CTTS::setEntryCount(uint32_t newEntryCount){
-    setInt32(newEntryCount, 4);
-  }
-  
-  uint32_t CTTS::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void CTTS::setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no){
-    if(no + 1 > getEntryCount()){
-      for (unsigned int i = getEntryCount(); i < no; i++){
-        setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits
-      }
-    }
-    setInt32(newCTTSEntry.sampleCount, 8 + no * 8);
-    setInt32(newCTTSEntry.sampleOffset, 8 + (no * 8) + 4);
-  }
-  
-  CTTSEntry CTTS::getCTTSEntry(uint32_t no){
-    static CTTSEntry retval;
-    if (no >= getEntryCount()){
-      static CTTSEntry inval;
-      return inval;
-    }
-    retval.sampleCount = getInt32(8 + (no * 8));
-    retval.sampleOffset = getInt32(8 + (no * 8) + 4);
-    return retval;
-  }
-  
-  std::string CTTS::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      static CTTSEntry temp;
-      temp = getCTTSEntry(i);
-      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
-      r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl;
-      r << std::string(indent + 2, ' ') << "SampleOffset: " << temp.sampleOffset << std::endl;
-    }
-    return r.str();
-
-  }
-
-  STSC::STSC(char v, uint32_t f){
-    memcpy(data + 4, "stsc", 4);
-    setVersion(v);
-    setFlags(f);
-    setEntryCount(0);
-  }
-  
-  void STSC::setEntryCount(uint32_t newEntryCount){
-    setInt32(newEntryCount, 4);
-  }
-  
-  uint32_t STSC::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void STSC::setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no){
-    if(no + 1 > getEntryCount()){
-      setEntryCount(no+1);
-      for (unsigned int i = getEntryCount(); i < no; i++){
-        setInt64(0, 8 + (i * 12));//filling up undefined entries of 64 bits
-        setInt32(0, 8 + (i * 12) + 8);
-      }
-    }
-    setInt32(newSTSCEntry.firstChunk, 8 + no * 12);
-    setInt32(newSTSCEntry.samplesPerChunk, 8 + (no * 12) + 4);
-    setInt32(newSTSCEntry.sampleDescriptionIndex, 8 + (no * 12) + 8);
-  }
-  
-  STSCEntry STSC::getSTSCEntry(uint32_t no){
-    static STSCEntry retval;
-    if (no >= getEntryCount()){
-      static STSCEntry inval;
-      return inval;
-    }
-    retval.firstChunk = getInt32(8 + (no * 12));
-    retval.samplesPerChunk = getInt32(8 + (no * 12) + 4);
-    retval.sampleDescriptionIndex = getInt32(8 + (no * 12) + 8);
-    return retval;
-  }
-  
-  std::string STSC::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stsc] Sample To Chunk Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      static STSCEntry temp;
-      temp = getSTSCEntry(i);
-      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
-      r << std::string(indent + 2, ' ') << "FirstChunk: " << temp.firstChunk << std::endl;
-      r << std::string(indent + 2, ' ') << "SamplesPerChunk: " << temp.samplesPerChunk << std::endl;
-      r << std::string(indent + 2, ' ') << "SampleDescriptionIndex: " << temp.sampleDescriptionIndex << std::endl;
-    }
-    return r.str();
-  }
-  
-  STCO::STCO(char v, uint32_t f){
-    memcpy(data + 4, "stco", 4);
-    setVersion(v);
-    setFlags(f);
-    setEntryCount(0);
-  }
-  
-  void STCO::setEntryCount(uint32_t newEntryCount){
-    setInt32(newEntryCount, 4);
-  }
-  
-  uint32_t STCO::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void STCO::setChunkOffset(uint32_t newChunkOffset, uint32_t no){
-    if (no + 1 > getEntryCount()){
-      for (unsigned int i = getEntryCount(); i < no; i++){
-        setInt32(0, 8 + i * 4);//filling undefined entries
-      }
-      setEntryCount(no+1);
-    }
-    setInt32(newChunkOffset, 8 + no * 4);  
-  }
-  
-  uint32_t STCO::getChunkOffset(uint32_t no){
-    if (no >= getEntryCount()){
-      return 0;
-    }
-    return getInt32(8 + no * 4);
-  }
-  
-  std::string STCO::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stco] Chunk Offset Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      r << std::string(indent + 1, ' ') << "ChunkOffset[" << i <<"]: " << getChunkOffset(i) << std::endl;
-    }
-    return r.str();
-  }
-
-  STSZ::STSZ(char v, uint32_t f){
-    memcpy(data + 4, "stsz", 4);
-    setVersion(v);
-    setFlags(f);
-    setSampleCount(0);
-  }
-
-  void STSZ::setSampleSize(uint32_t newSampleSize){
-    setInt32(newSampleSize, 4);
-  }
-  
-  uint32_t STSZ::getSampleSize(){
-    return getInt32(4);
-  }
-  
-  void STSZ::setSampleCount(uint32_t newSampleCount){
-    setInt32(newSampleCount, 8);
-  }
-  
-  uint32_t STSZ::getSampleCount(){
-    return getInt32(8);
-  }
-  
-  void STSZ::setEntrySize(uint32_t newEntrySize, uint32_t no){
-    if (no + 1 > getSampleCount()){
-      setSampleCount(no + 1);
-      for (unsigned int i = getSampleCount(); i < no; i++){
-        setInt32(0, 12 + i * 4);//filling undefined entries
-      }
-    }
-    setInt32(newEntrySize, 12 + no * 4);
-  }
-  
-  uint32_t STSZ::getEntrySize(uint32_t no){
-    if (no >= getSampleCount()){
-      return 0;
-    }
-    return getInt32(12 + no * 4);
-  }
-  
-  std::string STSZ::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stsz] Sample Size Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl;
-    r << std::string(indent + 1, ' ') << "SampleCount: " << getSampleCount() << std::endl;
-    for (unsigned int i = 0; i < getSampleCount(); i++){
-      r << std::string(indent + 1, ' ') << "EntrySize[" << i <<"]: " << getEntrySize(i) << std::endl;
-    }
-    return r.str();
-  }
-
-  SampleEntry::SampleEntry(){
-    memcpy(data + 4, "erro", 4);
-  }
-  
-  void SampleEntry::setDataReferenceIndex(uint16_t newDataReferenceIndex){
-    setInt16(newDataReferenceIndex, 6);
-  }
-  
-  uint16_t SampleEntry::getDataReferenceIndex(){
-    return getInt16(6);
-  }
-  
-  std::string SampleEntry::toPrettySampleString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent + 1, ' ') << "DataReferenceIndex: " << getDataReferenceIndex() << std::endl;
-    return r.str();  
-  }
-
-  CLAP::CLAP(){
-    memcpy(data + 4, "clap", 4);
-    setHorizOffN(0);
-    setHorizOffD(0);
-    setVertOffN(0);
-    setVertOffD(0);
-  }
-  
-  void CLAP::setCleanApertureWidthN(uint32_t newVal){
-    setInt32(newVal,0);  
-  }
-  
-  uint32_t CLAP::getCleanApertureWidthN(){
-    return getInt32(0);
-  }
-  
-  void CLAP::setCleanApertureWidthD(uint32_t newVal){
-    setInt32(newVal,4);
-  }
-  
-  uint32_t CLAP::getCleanApertureWidthD(){
-    return getInt32(4);
-  }
-  
-  void CLAP::setCleanApertureHeightN(uint32_t newVal){
-    setInt32(newVal,8);
-  }
-  
-  uint32_t CLAP::getCleanApertureHeightN(){
-    return getInt32(8);
-  }
-  
-  void CLAP::setCleanApertureHeightD(uint32_t newVal){
-    setInt32(newVal, 12);
-  }
-  
-  uint32_t CLAP::getCleanApertureHeightD(){
-    return getInt32(12);
-  }
-  
-  void CLAP::setHorizOffN(uint32_t newVal){
-    setInt32(newVal, 16);
-  }
-  
-  uint32_t CLAP::getHorizOffN(){
-    return getInt32(16);
-  }
-  
-  void CLAP::setHorizOffD(uint32_t newVal){
-    setInt32(newVal, 20);
-  }
-  
-  uint32_t CLAP::getHorizOffD(){
-    return getInt32(20);
-  }
-  
-  void CLAP::setVertOffN(uint32_t newVal){
-    setInt32(newVal, 24);
-  }
-  
-  uint32_t CLAP::getVertOffN(){
-    return getInt32(24);
-  }
-  
-  void CLAP::setVertOffD(uint32_t newVal){
-    setInt32(newVal, 28);
-  }
-  
-  uint32_t CLAP::getVertOffD(){
-    return getInt32(32);
-  }
-  
-  std::string CLAP::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[clap] Clean Aperture Box (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "CleanApertureWidthN: " << getCleanApertureWidthN() << std::endl;
-    r << std::string(indent + 1, ' ') << "CleanApertureWidthD: " << getCleanApertureWidthD() << std::endl;
-    r << std::string(indent + 1, ' ') << "CleanApertureHeightN: " << getCleanApertureHeightN() << std::endl;
-    r << std::string(indent + 1, ' ') << "CleanApertureHeightD: " << getCleanApertureHeightD() << std::endl;
-    r << std::string(indent + 1, ' ') << "HorizOffN: " << getHorizOffN() << std::endl;
-    r << std::string(indent + 1, ' ') << "HorizOffD: " << getHorizOffD() << std::endl;
-    r << std::string(indent + 1, ' ') << "VertOffN: " << getVertOffN() << std::endl;
-    r << std::string(indent + 1, ' ') << "VertOffD: " << getVertOffD() << std::endl;
-    return r.str();
-  }
-  
-  PASP::PASP(){
-    memcpy(data + 4, "pasp", 4);
-  }
-  
-  void PASP::setHSpacing(uint32_t newVal){
-    setInt32(newVal, 0);
-  }
-  
-  uint32_t PASP::getHSpacing(){
-    return getInt32(0);
-  }
-  
-  void PASP::setVSpacing(uint32_t newVal){
-    setInt32(newVal, 4);
-  }
-  
-  uint32_t PASP::getVSpacing(){
-    return getInt32(4);
-  }
-  
-  std::string PASP::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[pasp] Pixel Aspect Ratio Box (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "HSpacing: " << getHSpacing() << std::endl;
-    r << std::string(indent + 1, ' ') << "VSpacing: " << getVSpacing() << std::endl;
-    return r.str();
-  }
-
-  VisualSampleEntry::VisualSampleEntry(){
-    memcpy(data + 4, "erro", 4);
-    setHorizResolution(0x00480000);
-    setVertResolution(0x00480000);
-    setFrameCount(1);
-    setCompressorName("");
-    setDepth(0x0018);
-  }
-  
-  void VisualSampleEntry::setCodec(const char* newCodec){
-    memcpy(data + 4, newCodec, 4);
-  }
-  
-  void VisualSampleEntry::setWidth(uint16_t newWidth){
-    setInt16(newWidth,24);
-  }
-  
-  uint16_t VisualSampleEntry::getWidth(){
-    return getInt16(24);
-  }
-  
-  void VisualSampleEntry::setHeight(uint16_t newHeight){
-    setInt16(newHeight, 26);
-  }
-  
-  uint16_t VisualSampleEntry::getHeight(){
-    return getInt16(26);
-  }
-  
-  void VisualSampleEntry::setHorizResolution (uint32_t newHorizResolution){
-    setInt32(newHorizResolution, 28);
-  }
-  
-  uint32_t VisualSampleEntry::getHorizResolution(){
-    return getInt32(28);
-  }
-  
-  void VisualSampleEntry::setVertResolution (uint32_t newVertResolution){
-    setInt32(newVertResolution,32);
-  }
-  
-  uint32_t VisualSampleEntry::getVertResolution(){
-    return getInt32(32);
-  }
-  
-  void VisualSampleEntry::setFrameCount(uint16_t newFrameCount){
-    setInt16(newFrameCount, 40);
-  }
-  
-  uint16_t VisualSampleEntry::getFrameCount(){
-    return getInt16(40);
-  }
-
-  void VisualSampleEntry::setCompressorName(std::string newCompressorName){
-    newCompressorName.resize(32, ' ');
-    setString(newCompressorName,42);
-  }
-  
-  std::string VisualSampleEntry::getCompressorName(){
-    return getString(42);
-  }
-
-  void VisualSampleEntry::setDepth(uint16_t newDepth){
-    setInt16(newDepth, 74);
-  }
-  
-  uint16_t VisualSampleEntry::getDepth(){
-    return getInt16(74);
-  }
-
-  void VisualSampleEntry::setCLAP(Box& clap){
-    setBox(clap,78);
-  }
-
-  Box & VisualSampleEntry::getCLAP(){
-    static Box ret = Box((char*)"\000\000\000\010erro", false);
-    if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP
-      ret = Box((char*)"\000\000\000\010erro", false);
-      return ret;
-    }
-    ret = Box(getBox(78).asBox(), false);
-    return ret;
-  }
-  
-  Box & VisualSampleEntry::getPASP(){
-    static Box ret = Box((char*)"\000\000\000\010erro", false);
-    if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP
-      ret = Box((char*)"\000\000\000\010erro", false);
-      return ret;
-    }
-    if (payloadSize() < 78 + getBoxLen(78) + 8){
-      ret = Box((char*)"\000\000\000\010erro", false);
-      return ret;
-    }
-    ret = Box(getBox(78 + getBoxLen(78)).asBox(), false);
-    return ret;
-  }
-  
-  std::string VisualSampleEntry::toPrettyVisualString(uint32_t indent, std::string name){
-    std::stringstream r;
-    r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl;
-    r << toPrettySampleString(indent);
-    r << std::string(indent + 1, ' ') << "Width: " << getWidth() << std::endl;
-    r << std::string(indent + 1, ' ') << "Height: " << getHeight() << std::endl;
-    r << std::string(indent + 1, ' ') << "HorizResolution: " << getHorizResolution() << std::endl;
-    r << std::string(indent + 1, ' ') << "VertResolution: " << getVertResolution() << std::endl;
-    r << std::string(indent + 1, ' ') << "FrameCount: " << getFrameCount() << std::endl;
-    r << std::string(indent + 1, ' ') << "CompressorName: " << getCompressorName() << std::endl;
-    r << std::string(indent + 1, ' ') << "Depth: " << getDepth() << std::endl;
-    if (!getCLAP().isType("erro")){
-      r << getCLAP().toPrettyString(indent+1);
-    }
-    if (!getPASP().isType("erro")){
-      r << getPASP().toPrettyString(indent+1);
-    }
-    return r.str();
-  }
-
-  AudioSampleEntry::AudioSampleEntry(){
-    memcpy(data + 4, "erro", 4);
-    setChannelCount(2);
-    setSampleSize(16);
-    setSampleRate(44100);
-  }
-
-  void AudioSampleEntry::setCodec(const char* newCodec){
-    memcpy(data + 4, newCodec, 4);
-  }
-  
-  void AudioSampleEntry::setChannelCount(uint16_t newChannelCount){
-    setInt16(newChannelCount,16);
-  }
-  
-  uint16_t AudioSampleEntry::getChannelCount(){
-    return getInt16(16);
-  }
-  
-  void AudioSampleEntry::setSampleSize(uint16_t newSampleSize){
-    setInt16(newSampleSize,18);
-  }
-  
-  uint16_t AudioSampleEntry::getSampleSize(){
-    return getInt16(18);
-  }
-  
-  void AudioSampleEntry::setPreDefined(uint16_t newPreDefined){
-    setInt16(newPreDefined,20);
-  }
-  
-  uint16_t AudioSampleEntry::getPreDefined(){
-    return getInt16(20);
-  }
-  
-  void AudioSampleEntry::setSampleRate(uint32_t newSampleRate){
-    setInt32(newSampleRate << 16, 24);
-  }
-  
-  uint32_t AudioSampleEntry::getSampleRate(){
-    return getInt32(24) >> 16;
-  }
-
-  uint16_t AudioSampleEntry::toAACInit(){
-    uint16_t result = 0;
-    result |= (2 & 0x1F) << 11;
-    result |= (getSampleRate() & 0x0F) << 7;
-    result |= (getChannelCount() & 0x0F) << 3;
-    return result;
-  }
-  
-  void AudioSampleEntry::setCodecBox(Box& newBox){
-    setBox(newBox, 28);
-  }
-  
-  Box & AudioSampleEntry::getCodecBox(){
-    return getBox(28);
-  }
-  
-  std::string AudioSampleEntry::toPrettyAudioString(uint32_t indent, std::string name){
-    std::stringstream r;
-    r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl;
-    r << toPrettySampleString(indent);
-    r << std::string(indent + 1, ' ') << "ChannelCount: " << getChannelCount() << std::endl;
-    r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl;
-    r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl;
-    r << std::string(indent + 1, ' ') << "SampleRate: " << getSampleRate() << std::endl;
-    r << getCodecBox().toPrettyString(indent + 1);
-    return r.str();
-  }
-
-  MP4A::MP4A(){
-    memcpy(data + 4, "mp4a", 4);
-  }
-  
-  std::string MP4A::toPrettyString(uint32_t indent){
-    return toPrettyAudioString(indent, "[mp4a] MPEG-4 Audio");
-  }
-
-  AAC::AAC(){
-    memcpy(data + 4, "aac ", 4);
-  }
-  
-  std::string AAC::toPrettyString(uint32_t indent){
-    return toPrettyAudioString(indent, "[aac ] Advanced Audio Codec");
-  }
-
-  AVC1::AVC1(){
-    memcpy(data + 4, "avc1", 4);
-  }
-  
-  std::string AVC1::toPrettyString(uint32_t indent){
-    return toPrettyVisualString(indent, "[avc1] Advanced Video Codec 1");
-  }
-
-  H264::H264(){
-    memcpy(data + 4, "h264", 4);
-  }
-  
-  std::string H264::toPrettyString(uint32_t indent){
-    return toPrettyVisualString(indent, "[h264] H.264/MPEG-4 AVC");
-  }
-
-  STSD::STSD(char v, uint32_t f){
-    memcpy(data + 4, "stsd", 4);
-    setVersion(v);
-    setFlags(f);
-    setEntryCount(0);
-  }
-
-  void STSD::setEntryCount (uint32_t newEntryCount){
-    setInt32(newEntryCount, 4);
-  }
-  
-  uint32_t STSD::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void STSD::setEntry(Box & newContent, uint32_t no){
-    int tempLoc = 8;
-    unsigned int entryCount = getEntryCount();
-    for (unsigned int i = 0; i < no; i++){
-      if (i < entryCount){
-        tempLoc += getBoxLen(tempLoc);
-      }else{
-        if ( !reserve(tempLoc, 0, (no - entryCount) * 8)){
-          return;
-        }
-        memset(data + tempLoc, 0, (no - entryCount) * 8);
-        tempLoc += (no - entryCount) * 8;
-        break;
-      }
-    }
-    setBox(newContent, tempLoc);
-    if (getEntryCount() < no+1){
-      setEntryCount(no+1);
-    }
-  }
-  
-  Box & STSD::getEntry(uint32_t no){
-    static Box ret = Box((char*)"\000\000\000\010erro", false);
-    if (no > getEntryCount()){
-      return ret;
-    }
-    unsigned int i = 0;
-    int tempLoc = 8;
-    while (i < no){
-      tempLoc += getBoxLen(tempLoc);
-      i++;
-    }
-    return getBox(tempLoc);
-  }
-
-  std::string STSD::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stsd] Sample Description Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntrySize: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      Box curBox = Box(getEntry(i).asBox(), false);
-      r << curBox.toPrettyString(indent + 1);
-    }
-    return r.str();
-  }
-
-  EDTS::EDTS(){
-    memcpy(data + 4, "edts", 4);
-  }
-
-  std::string EDTS::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[edts] Edit Box"));
-  }
-  
-  UDTA::UDTA(){
-    memcpy(data + 4, "udta", 4);
-  }
-
-  std::string UDTA::toPrettyString(uint32_t indent){
-    return toPrettyContainerString(indent, std::string("[udta] User Data Box"));
-  }
-
-  STSS::STSS(char v, uint32_t f){
-    memcpy(data + 4, "stss", 4);
-    setVersion(v);
-    setFlags(f);
-    setEntryCount(0);
-  }
-  
-  void STSS::setEntryCount(uint32_t newVal){
-    setInt32(newVal, 4);
-  }
-  
-  uint32_t STSS::getEntryCount(){
-    return getInt32(4);
-  }
-  
-  void STSS::setSampleNumber(uint32_t newVal, uint32_t index){
-    if (index >= getEntryCount()){
-      setEntryCount(index + 1);
-    }
-    setInt32(newVal, 8 + (index * 4));
-  }
-  
-  uint32_t STSS::getSampleNumber(uint32_t index){
-    if (index >= getEntryCount()){
-      return 0;
-    }
-    return getInt32(8 + (index * 4));
-  }
-  
-  std::string STSS::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[stss] Sync Sample Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
-    for (unsigned int i = 0; i < getEntryCount(); i++){
-      r << std::string(indent + 1, ' ') << "SampleNumber[" << i <<"] : " << getSampleNumber(i) << std::endl;
-    }
-    return r.str();
-  }
-
-  META::META(){
-    memcpy(data + 4, "meta", 4);
-  }
-  
-  std::string META::toPrettyString(uint32_t indent){
-    return toPrettyCFBString(indent, "[meta] Meta Box");
-  }
-
-  ELST::ELST(){
-    memcpy(data + 4, "elst", 4);
-  }
-  
-  void ELST::setSegmentDuration(uint64_t newVal){
-    if (getVersion() == 1){
-      setInt64(newVal, 4);
-    }else{
-      setInt32(newVal, 4);
-    }
-  }
-  
-  uint64_t ELST::getSegmentDuration(){
-    if (getVersion() == 1){
-      return getInt64(4);
-    }else{
-      return getInt32(4);
-    }
-  }
-  
-  void ELST::setMediaTime(uint64_t newVal){
-    if (getVersion() == 1){
-      setInt64(newVal, 12);
-    }else{
-      setInt32(newVal, 8);
-    }
-  }
-  
-  uint64_t ELST::getMediaTime(){
-    if (getVersion() == 1){
-      return getInt64(12);
-    }else{
-      return getInt32(8);
-    }
-  }
-  
-  void ELST::setMediaRateInteger(uint16_t newVal){
-    if (getVersion() == 1){
-      setInt16(newVal, 20);
-    }else{
-      setInt16(newVal, 12);
-    }
-  }
-  
-  uint16_t ELST::getMediaRateInteger(){
-    if (getVersion() == 1){
-      return getInt16(20);
-    }else{
-      return getInt16(12);
-    }
-  }
-  
-  void ELST::setMediaRateFraction(uint16_t newVal){
-    if (getVersion() == 1){
-      setInt16(newVal, 22);
-    }else{
-      setInt16(newVal, 14);
-    }
-  }
-  
-  uint16_t ELST::getMediaRateFraction(){
-    if (getVersion() == 1){
-      return getInt16(22);
-    }else{
-      return getInt16(14);
-    }
-  }
-  
-  std::string ELST::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl;
-    r << fullBox::toPrettyString(indent);
-    r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl;
-    r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl;
-    r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl;
-    r << std::string(indent + 1, ' ') << "MediaRateFraction: " << getMediaRateFraction() << std::endl;
-    return r.str();
-  }
-
-  static char c2hex(int c){
-    if (c >= '0' && c <= '9') return c - '0';
-    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
-    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
-    return 0;
-  }
-  
-  UUID::UUID(){
-    memcpy(data + 4, "uuid", 4);
-    setInt64(0, 0);
-    setInt64(0, 8);
-  }
-
-  std::string UUID::getUUID(){
-    std::stringstream r;
-    r << std::hex;
-    for (int i = 0; i < 16; ++i){
-      if (i == 4 || i == 6 || i == 8 || i == 10){
-        r << "-";
-      }
-      r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8+i]);
-    }
-    return r.str();
-  }
-
-  void UUID::setUUID(const std::string & uuid_string){
-    //reset UUID to zero
-    for (int i = 0; i < 4; ++i){
-      ((uint32_t*)(data+8))[i] = 0;
-    }
-    //set the UUID from the string, char by char
-    int i = 0;
-    for (size_t j = 0; j < uuid_string.size(); ++j){
-      if (uuid_string[j] == '-'){
-        continue;
-      }
-      data[8+i/2] |= (c2hex(uuid_string[j]) << ((~i & 1) << 2));
-      ++i;
-    }
-  }
-
-  void UUID::setUUID(const char * raw_uuid){
-    memcpy(data+8, raw_uuid, 16);
-  }
-
-  std::string UUID::toPrettyString(uint32_t indent){
-    std::string UUID = getUUID();
-    if (UUID == "d4807ef2-ca39-4695-8e54-26cb9e46a79f"){
-      return ((UUID_TrackFragmentReference*)this)->toPrettyString(indent);
-    }
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[uuid] Extension box (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "UUID: " << UUID << std::endl;
-    r << std::string(indent + 1, ' ') << "Unknown UUID - ignoring contents." << std::endl;
-    return r.str();
-  }
-
-  UUID_TrackFragmentReference::UUID_TrackFragmentReference(){
-    setUUID((std::string)"d4807ef2-ca39-4695-8e54-26cb9e46a79f");
-  }
-
-  void UUID_TrackFragmentReference::setVersion(uint32_t newVersion){
-    setInt8(newVersion, 16);
-  }
-  
-  uint32_t UUID_TrackFragmentReference::getVersion(){
-    return getInt8(16);
-  }
-  
-  void UUID_TrackFragmentReference::setFlags(uint32_t newFlags){
-    setInt24(newFlags, 17);
-  }
-  
-  uint32_t UUID_TrackFragmentReference::getFlags(){
-    return getInt24(17);
-  }
-  
-  void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount){
-    setInt8(newCount, 20);
-  }
-  
-  uint32_t UUID_TrackFragmentReference::getFragmentCount(){
-    return getInt8(20);
-  }
-  
-  void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime){
-    if (getVersion() == 0){
-      setInt32(newTime, 21+(num*8));
-    }else{
-      setInt64(newTime, 21+(num*16));
-    }
-  }
-  
-  uint64_t UUID_TrackFragmentReference::getTime(size_t num){
-    if (getVersion() == 0){
-      return getInt32(21+(num*8));
-    }else{
-      return getInt64(21+(num*16));
-    }
-  }
-  
-  void UUID_TrackFragmentReference::setDuration(size_t num, uint64_t newDuration){
-    if (getVersion() == 0){
-      setInt32(newDuration, 21+(num*8)+4);
-    }else{
-      setInt64(newDuration, 21+(num*16)+8);
-    }
-  }
-  
-  uint64_t UUID_TrackFragmentReference::getDuration(size_t num){
-    if (getVersion() == 0){
-      return getInt32(21+(num*8)+4);
-    }else{
-      return getInt64(21+(num*16)+8);
-    }
-  }
-
-  std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent){
-    std::stringstream r;
-    r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference (" << boxedSize() << ")" << std::endl;
-    r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
-    r << std::string(indent + 1, ' ') << "Fragments: " << getFragmentCount() << std::endl;
-    int j = getFragmentCount();
-    for (int i = 0; i < j; ++i){
-      r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i) << ", Duration = " << getDuration(i) << std::endl;
-    }
-    return r.str();
-  }
-
-
 }
diff --git a/lib/mp4.h b/lib/mp4.h
index 0715171e..4eeb18de 100644
--- a/lib/mp4.h
+++ b/lib/mp4.h
@@ -28,27 +28,16 @@ namespace MP4 {
         }
         return false;
       }
-      long long int trackID;
-      long long int size;
-      long long int time;
-      long long int len;
-      std::deque<DTSC::Part> parts;
-      long long int partsize;
+      long unsigned int trackID;
+      long unsigned int size;
+      long long unsigned int time;
+      long long unsigned int endTime;
+      long unsigned int index;
   };
 
   class DTSC2MP4Converter{
     public:
       std::string DTSCMeta2MP4Header(DTSC::Meta & metaData);
-      void parseDTSC(JSON::Value mediaPart);
-      bool sendReady();
-      std::string sendString();
-      std::string purgeBuffer();
-      std::set <keyPart> keyParts;
-    private:
-      //long long unsigned int curKey;//the key chunk we are currently searching for in keyParts
-      //long long unsigned int curPart;//current part in current key
-      std::map <long long unsigned int, std::deque<JSON::Value> > trackBuffer;
-      std::string stringBuffer;
   };
   
   class Box{
@@ -89,7 +78,7 @@ namespace MP4 {
       bool reserve(size_t position, size_t current, size_t wanted);
       //internal variables
       char * data; ///< Holds the data of this box
-      int data_size; ///< Currently reserved size
+      unsigned int data_size; ///< Currently reserved size
       bool managed; ///< If false, will not attempt to resize/free the data pointer.
       int payloadOffset; ///<The offset of the payload with regards to the data
   };
@@ -112,7 +101,6 @@ namespace MP4 {
       void setContent(Box & newContent, uint32_t no);
       Box & getContent(uint32_t no);
       std::string toPrettyString(uint32_t indent = 0);
-      std::string toPrettyContainerString(uint32_t indent, std::string boxName);
   };
   
   class containerFullBox: public fullBox{
@@ -122,860 +110,4 @@ namespace MP4 {
       Box & getContent(uint32_t no);
       std::string toPrettyCFBString(uint32_t indent, std::string boxName);
   };
-
-  struct afrt_runtable{
-      uint32_t firstFragment;
-      uint64_t firstTimestamp;
-      uint32_t duration;
-      uint32_t discontinuity;
-  };
-  //fragmentRun
-
-  /// AFRT Box class
-  class AFRT: public Box{
-    public:
-      AFRT();
-      void setVersion(char newVersion);
-      uint32_t getVersion();
-      void setUpdate(uint32_t newUpdate);
-      uint32_t getUpdate();
-      void setTimeScale(uint32_t newScale);
-      uint32_t getTimeScale();
-      uint32_t getQualityEntryCount();
-      void setQualityEntry(std::string & newQuality, uint32_t no);
-      const char * getQualityEntry(uint32_t no);
-      uint32_t getFragmentRunCount();
-      void setFragmentRun(afrt_runtable newRun, uint32_t no);
-      afrt_runtable getFragmentRun(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //AFRT Box
-
-  struct asrt_runtable{
-      uint32_t firstSegment;
-      uint32_t fragmentsPerSegment;
-  };
-
-  /// ASRT Box class
-  class ASRT: public Box{
-    public:
-      ASRT();
-      void setVersion(char newVersion);
-      uint32_t getVersion();
-      void setUpdate(uint32_t newUpdate);
-      uint32_t getUpdate();
-      uint32_t getQualityEntryCount();
-      void setQualityEntry(std::string & newQuality, uint32_t no);
-      const char* getQualityEntry(uint32_t no);
-      uint32_t getSegmentRunEntryCount();
-      void setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no);
-      asrt_runtable getSegmentRun(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //ASRT Box
-
-  /// ABST Box class
-  class ABST: public Box{
-    public:
-      ABST();
-      void setVersion(char newVersion);
-      char getVersion();
-      void setFlags(uint32_t newFlags);
-      uint32_t getFlags();
-      void setBootstrapinfoVersion(uint32_t newVersion);
-      uint32_t getBootstrapinfoVersion();
-      void setProfile(char newProfile);
-      char getProfile();
-      void setLive(bool newLive);
-      bool getLive();
-      void setUpdate(bool newUpdate);
-      bool getUpdate();
-      void setTimeScale(uint32_t newTimeScale);
-      uint32_t getTimeScale();
-      void setCurrentMediaTime(uint64_t newTime);
-      uint64_t getCurrentMediaTime();
-      void setSmpteTimeCodeOffset(uint64_t newTime);
-      uint64_t getSmpteTimeCodeOffset();
-      void setMovieIdentifier(std::string & newIdentifier);
-      char * getMovieIdentifier();
-      uint32_t getServerEntryCount();
-      void setServerEntry(std::string & entry, uint32_t no);
-      const char * getServerEntry(uint32_t no);
-      uint32_t getQualityEntryCount();
-      void setQualityEntry(std::string & entry, uint32_t no);
-      const char * getQualityEntry(uint32_t no);
-      void setDrmData(std::string newDrm);
-      char * getDrmData();
-      void setMetaData(std::string newMetaData);
-      char * getMetaData();
-      uint32_t getSegmentRunTableCount();
-      void setSegmentRunTable(ASRT & table, uint32_t no);
-      ASRT & getSegmentRunTable(uint32_t no);
-      uint32_t getFragmentRunTableCount();
-      void setFragmentRunTable(AFRT & table, uint32_t no);
-      AFRT & getFragmentRunTable(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //ABST Box
-
-  class MFHD: public Box{
-    public:
-      MFHD();
-      void setSequenceNumber(uint32_t newSequenceNumber);
-      uint32_t getSequenceNumber();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //MFHD Box
-
-  /*class MOOF: public Box{
-    public:
-      MOOF();
-      uint32_t getContentCount();
-      void setContent(Box & newContent, uint32_t no);
-      Box & getContent(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };*/
-  
-  class MOOF: public containerBox{
-    public:
-      MOOF();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //MOOF Box
-
-  class TRAF: public Box{
-    public:
-      TRAF();
-      uint32_t getContentCount();
-      void setContent(Box & newContent, uint32_t no);
-      Box & getContent(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  //TRAF Box
-
-  struct trunSampleInformation{
-      uint32_t sampleDuration;
-      uint32_t sampleSize;
-      uint32_t sampleFlags;
-      int32_t sampleOffset;
-  };
-  enum trunflags{
-    trundataOffset = 0x00000001,
-    trunfirstSampleFlags = 0x00000004,
-    trunsampleDuration = 0x00000100,
-    trunsampleSize = 0x00000200,
-    trunsampleFlags = 0x00000400,
-    trunsampleOffsets = 0x00000800
-  };
-  enum sampleflags{
-    noIPicture = 0x01000000,
-    isIPicture = 0x02000000,
-    noDisposable = 0x00400000,
-    isDisposable = 0x00800000,
-    isRedundant = 0x00100000,
-    noRedundant = 0x00200000,
-    noKeySample = 0x00010000,
-    isKeySample = 0x00000000,
-    MUST_BE_PRESENT = 0x1
-  };
-  std::string prettySampleFlags(uint32_t flag);
-  class TRUN: public Box{
-    public:
-      TRUN();
-      void setFlags(uint32_t newFlags);
-      uint32_t getFlags();
-      void setDataOffset(uint32_t newOffset);
-      uint32_t getDataOffset();
-      void setFirstSampleFlags(uint32_t newSampleFlags);
-      uint32_t getFirstSampleFlags();
-      uint32_t getSampleInformationCount();
-      void setSampleInformation(trunSampleInformation newSample, uint32_t no);
-      trunSampleInformation getSampleInformation(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  enum tfhdflags{
-    tfhdBaseOffset = 0x000001,
-    tfhdSampleDesc = 0x000002,
-    tfhdSampleDura = 0x000008,
-    tfhdSampleSize = 0x000010,
-    tfhdSampleFlag = 0x000020,
-    tfhdNoDuration = 0x010000,
-  };
-  class TFHD: public Box{
-    public:
-      TFHD();
-      void setFlags(uint32_t newFlags);
-      uint32_t getFlags();
-      void setTrackID(uint32_t newID);
-      uint32_t getTrackID();
-      void setBaseDataOffset(uint64_t newOffset);
-      uint64_t getBaseDataOffset();
-      void setSampleDescriptionIndex(uint32_t newIndex);
-      uint32_t getSampleDescriptionIndex();
-      void setDefaultSampleDuration(uint32_t newDuration);
-      uint32_t getDefaultSampleDuration();
-      void setDefaultSampleSize(uint32_t newSize);
-      uint32_t getDefaultSampleSize();
-      void setDefaultSampleFlags(uint32_t newFlags);
-      uint32_t getDefaultSampleFlags();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  struct afraentry{
-      uint64_t time;
-      uint64_t offset;
-  };
-  struct globalafraentry{
-      uint64_t time;
-      uint32_t segment;
-      uint32_t fragment;
-      uint64_t afraoffset;
-      uint64_t offsetfromafra;
-  };
-  class AFRA: public Box{
-    public:
-      AFRA();
-      void setVersion(uint32_t newVersion);
-      uint32_t getVersion();
-      void setFlags(uint32_t newFlags);
-      uint32_t getFlags();
-      void setLongIDs(bool newVal);
-      bool getLongIDs();
-      void setLongOffsets(bool newVal);
-      bool getLongOffsets();
-      void setGlobalEntries(bool newVal);
-      bool getGlobalEntries();
-      void setTimeScale(uint32_t newVal);
-      uint32_t getTimeScale();
-      uint32_t getEntryCount();
-      void setEntry(afraentry newEntry, uint32_t no);
-      afraentry getEntry(uint32_t no);
-      uint32_t getGlobalEntryCount();
-      void setGlobalEntry(globalafraentry newEntry, uint32_t no);
-      globalafraentry getGlobalEntry(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class AVCC: public Box{
-    public:
-      AVCC();
-      void setVersion(uint32_t newVersion);
-      uint32_t getVersion();
-      void setProfile(uint32_t newProfile);
-      uint32_t getProfile();
-      void setCompatibleProfiles(uint32_t newCompatibleProfiles);
-      uint32_t getCompatibleProfiles();
-      void setLevel(uint32_t newLevel);
-      uint32_t getLevel();
-      void setSPSNumber(uint32_t newSPSNumber);
-      uint32_t getSPSNumber();
-      void setSPS(std::string newSPS);
-      uint32_t getSPSLen();
-      char* getSPS();
-      void setPPSNumber(uint32_t newPPSNumber);
-      uint32_t getPPSNumber();
-      void setPPS(std::string newPPS);
-      uint32_t getPPSLen();
-      char* getPPS();
-      std::string asAnnexB();
-      void fromAnnexB(std::string annexBFormatted);
-      void setPayload(std::string newPayload);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  ///\todo : ESDS is filthy implemented, clean up when optimising
-  class ESDS: public fullBox{
-    public:
-      ESDS();
-      char getESDescriptorType();
-      void setESDescriptorType(char newVal);
-      uint32_t getExtendedESDescriptorType();//3 bytes
-      void setExtendedESDescriptorType(uint32_t newVal);//3 bytes
-      char getESDescriptorTypeLength();
-      void setESDescriptorTypeLength(char newVal);
-      //ESID 2 bytes
-      uint16_t getESID();
-      void setESID(uint16_t newVal);
-      //stream priority 1 byte
-      char getStreamPriority();
-      void setStreamPriority(char newVal);
-      //decoder config descriptor tag 1byte
-      char getDecoderConfigDescriptorTag();
-      void setDecoderConfigDescriptorTag(char newVal);
-      //extended decoder config descriptor tag 3 bytes
-      uint32_t getExtendedDecoderConfigDescriptorTag();
-      void setExtendedDecoderConfigDescriptorTag(uint32_t newVal);//3 bytes
-      //decoder config descriptor type length
-      char getDecoderConfigDescriptorTypeLength();
-      void setDecoderConfigDescriptorTypeLength(char newVal);
-      char getByteObjectTypeID();
-      void setByteObjectTypeID(char newVal);
-      char getStreamType();//6 bits
-      void setStreamType(char newVal);//6 bits
-      bool getUpstreamFlag();
-      void setUpstreamFlag(bool newVal);
-      bool getReservedFlag();
-      void setReservedFlag(bool newVal);
-      uint32_t getBufferSize();//3 bytes
-      void setBufferSize(uint32_t newVal);//3 bytes
-      uint32_t getMaximumBitRate();
-      void setMaximumBitRate(uint32_t newVal);
-      uint32_t getAverageBitRate();
-      void setAverageBitRate(uint32_t newVal);
-      char getDecoderDescriptorTypeTag();
-      void setDecoderDescriptorTypeTag(char newVal);
-      uint32_t getExtendedDecoderDescriptorTypeTag();//3 bytes
-      void setExtendedDecoderDescriptorTypeTag(uint32_t newVal);//3 bytes
-      char getConfigDescriptorTypeLength();
-      void setConfigDescriptorTypeLength(char newVal);
-      std::string getESHeaderStartCodes();
-      void setESHeaderStartCodes(std::string newVal);
-      char getSLConfigDescriptorTypeTag();
-      void setSLConfigDescriptorTypeTag(char newVal);
-      uint32_t getSLConfigExtendedDescriptorTypeTag();//3 bytes
-      void setSLConfigExtendedDescriptorTypeTag(uint32_t newVal);//3 bytes
-      char getSLDescriptorTypeLength();
-      void setSLDescriptorTypeLength(char newVal);
-      char getSLValue();
-      void setSLValue(char newVal);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class SDTP: public Box{
-    public:
-      SDTP();
-      void setVersion(uint32_t newVersion);
-      uint32_t getVersion();
-      void setValue(uint32_t newValue, size_t index);
-      uint32_t getValue(size_t index);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class FTYP: public Box{
-    public:
-      FTYP();
-      void setMajorBrand(uint32_t newMajorBrand);
-      uint32_t getMajorBrand();
-      void setMinorVersion(uint32_t newMinorVersion);
-      uint32_t getMinorVersion();
-      uint32_t getCompatibleBrandsCount();
-      void setCompatibleBrands(uint32_t newCompatibleBrand, size_t index);
-      uint32_t getCompatibleBrands(size_t index);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MOOV: public containerBox{
-    public:
-      MOOV();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MVEX: public containerBox{
-    public:
-      MVEX();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class TREX: public Box{
-    public:
-      TREX();
-      void setTrackID(uint32_t newTrackID);
-      uint32_t getTrackID();
-      void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
-      uint32_t getDefaultSampleDescriptionIndex();
-      void setDefaultSampleDuration(uint32_t newDefaultSampleDuration);
-      uint32_t getDefaultSampleDuration();
-      void setDefaultSampleSize(uint32_t newDefaultSampleSize);
-      uint32_t getDefaultSampleSize();
-      void setDefaultSampleFlags(uint32_t newDefaultSampleFlags);
-      uint32_t getDefaultSampleFlags();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  
-  class MFRA: public containerBox{
-    public:
-      MFRA();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class TRAK: public containerBox{
-    public:
-      TRAK();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MDIA: public containerBox{
-    public:
-      MDIA();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class MINF: public containerBox{
-    public:
-      MINF();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class DINF: public containerBox{
-    public:
-      DINF();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class MFRO: public Box{
-    public:
-      MFRO();
-      void setSize(uint32_t newSize);
-      uint32_t getSize();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class HDLR: public Box{
-    public:
-      HDLR();
-      void setSize(uint32_t newSize);
-      uint32_t getSize();
-      void setPreDefined(uint32_t newPreDefined);
-      uint32_t getPreDefined();
-      void setHandlerType(uint32_t newHandlerType);
-      uint32_t getHandlerType();
-      void setName(std::string newName);
-      std::string getName();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class VMHD: public fullBox{
-    public:
-      VMHD();
-      void setGraphicsMode(uint16_t newGraphicsMode);
-      uint16_t getGraphicsMode();
-      uint32_t getOpColorCount();
-      void setOpColor(uint16_t newOpColor, size_t index);
-      uint16_t getOpColor(size_t index);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class SMHD: public fullBox{
-    public:
-      SMHD();
-      void setBalance(int16_t newBalance);
-      int16_t getBalance();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class HMHD: public fullBox{
-    public:
-      HMHD();
-      void setMaxPDUSize(uint16_t newMaxPDUSize);
-      uint16_t getMaxPDUSize();
-      void setAvgPDUSize(uint16_t newAvgPDUSize);
-      uint16_t getAvgPDUSize();
-      void setMaxBitRate(uint32_t newMaxBitRate);
-      uint32_t getMaxBitRate();
-      void setAvgBitRate(uint32_t newAvgBitRate);
-      uint32_t getAvgBitRate();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class NMHD: public fullBox{
-    public:
-      NMHD();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MEHD: public fullBox{
-    public:
-      MEHD();
-      void setFragmentDuration(uint64_t newFragmentDuration);
-      uint64_t getFragmentDuration();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class STBL: public containerBox{
-    public:
-      STBL();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class URL: public fullBox{
-    public:
-      URL();
-      void setLocation(std::string newLocation);
-      std::string getLocation();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class URN: public fullBox{
-    public:
-      URN();
-      void setName(std::string newName);
-      std::string getName();
-      void setLocation(std::string newLocation);
-      std::string getLocation();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class DREF: public fullBox{
-    public:
-      DREF(char v = 1, uint32_t = 0);
-      uint32_t getEntryCount();
-      void setDataEntry(fullBox & newDataEntry, size_t index);
-      Box & getDataEntry(size_t index);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MVHD: public fullBox{
-    public:
-      MVHD(char v = 1, uint32_t f = 0);
-      void setCreationTime(uint64_t newCreationTime);
-      uint64_t getCreationTime();
-      void setModificationTime(uint64_t newModificationTime);
-      uint64_t getModificationTime();
-      void setTimeScale(uint32_t newTimeScale);
-      uint32_t getTimeScale();
-      void setDuration(uint64_t newDuration);
-      uint64_t getDuration();
-      void setRate(uint32_t newRate);
-      uint32_t getRate();
-      void setVolume(uint16_t newVolume);
-      uint16_t getVolume();
-      ///\todo fix default values
-      uint32_t getMatrixCount();
-      void setMatrix(int32_t newMatrix, size_t index);
-      int32_t getMatrix(size_t index);
-      void setTrackID(uint32_t newTrackID);
-      uint32_t getTrackID();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  struct TFRAEntry{
-    uint64_t time;
-    uint64_t moofOffset;
-    uint32_t trafNumber;
-    uint32_t trunNumber;
-    uint32_t sampleNumber;
-  };
-  
-  class TFRA: public fullBox{
-    public:
-      TFRA();
-      void setTrackID(uint32_t newTrackID);
-      uint32_t getTrackID();
-      void setLengthSizeOfTrafNum(char newVal);
-      char getLengthSizeOfTrafNum();
-      void setLengthSizeOfTrunNum(char newVal);
-      char getLengthSizeOfTrunNum();
-      void setLengthSizeOfSampleNum(char newVal);
-      char getLengthSizeOfSampleNum();
-      void setNumberOfEntry(uint32_t newNumberOfEntry);
-      uint32_t getNumberOfEntry();
-      void setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no);
-      TFRAEntry & getTFRAEntry(uint32_t no);
-      uint32_t getTFRAEntrySize();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class TKHD: public fullBox{
-    public:
-      TKHD(char v = 1, uint32_t f = 0);
-      void setCreationTime(uint64_t newCreationTime);
-      uint64_t getCreationTime();
-      void setModificationTime(uint64_t newModificationTime);
-      uint64_t getModificationTime();
-      void setTrackID(uint32_t newTrackID);
-      uint32_t getTrackID();
-      void setDuration(uint64_t newDuration);
-      uint64_t getDuration();
-
-      void setLayer(uint16_t newLayer);
-      uint16_t getLayer();
-      void setAlternateGroup(uint16_t newAlternateGroup);
-      uint16_t getAlternateGroup();
-
-      void setVolume(uint16_t newVolume);
-      uint16_t getVolume();
-      ///\todo fix default values
-      uint32_t getMatrixCount();
-      void setMatrix(int32_t newMatrix, size_t index);
-      int32_t getMatrix(size_t index);
-
-      void setWidth(uint32_t newWidth);
-      uint32_t getWidth();
-      void setHeight(uint32_t newHeight);
-      uint32_t getHeight();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class MDHD: public fullBox{
-    public:
-      MDHD(char v = 1, uint32_t f = 0);
-      void setCreationTime(uint64_t newCreationTime);
-      uint64_t getCreationTime();
-      void setModificationTime(uint64_t newModificationTime);
-      uint64_t getModificationTime();
-      void setTimeScale(uint32_t newTimeScale);
-      uint32_t getTimeScale();
-      void setDuration(uint64_t newDuration);
-      uint64_t getDuration();
-      ///\todo return language properly
-      void setLanguage(uint16_t newLanguage);
-      uint16_t getLanguage();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  struct STTSEntry{
-    uint32_t sampleCount;
-    uint32_t sampleDelta;
-  };
-  
-  class STTS: public fullBox{
-    public:
-      STTS(char v = 1, uint32_t f = 0);
-      void setEntryCount(uint32_t newEntryCount);
-      uint32_t getEntryCount();
-      void setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no);
-      STTSEntry getSTTSEntry(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  struct CTTSEntry{
-    uint32_t sampleCount;
-    uint32_t sampleOffset;
-  };
-
-  class CTTS: public fullBox{
-    public:
-      CTTS();
-      void setEntryCount(uint32_t newEntryCount);
-      uint32_t getEntryCount();
-      void setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no);
-      CTTSEntry getCTTSEntry(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  struct STSCEntry{
-    uint32_t firstChunk;
-    uint32_t samplesPerChunk;
-    uint32_t sampleDescriptionIndex;
-  };
-  
-  class STSC: public fullBox{
-    public:
-      STSC(char v = 1, uint32_t f = 0);
-      void setEntryCount(uint32_t newEntryCount);
-      uint32_t getEntryCount();
-      void setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no);
-      STSCEntry getSTSCEntry(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class STCO: public fullBox{
-    public:
-      STCO(char v = 1, uint32_t f = 0);
-      void setEntryCount(uint32_t newEntryCount);
-      uint32_t getEntryCount();
-      void setChunkOffset(uint32_t newChunkOffset, uint32_t no);
-      uint32_t getChunkOffset(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class STSZ: public fullBox{
-    public:
-      STSZ(char v = 1, uint32_t f = 0);
-      void setSampleSize(uint32_t newSampleSize);
-      uint32_t getSampleSize();
-      void setSampleCount(uint32_t newSampleCount);
-      uint32_t getSampleCount();
-      void setEntrySize(uint32_t newEntrySize, uint32_t no);
-      uint32_t getEntrySize(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class SampleEntry: public Box{
-    public:
-      SampleEntry();
-      void setDataReferenceIndex(uint16_t newDataReferenceIndex);
-      uint16_t getDataReferenceIndex();
-      std::string toPrettySampleString(uint32_t index);
-  };
-  
-  class CLAP: public Box{//CleanApertureBox
-    public:
-      CLAP();
-      void setCleanApertureWidthN(uint32_t newVal);
-      uint32_t getCleanApertureWidthN();
-      void setCleanApertureWidthD(uint32_t newVal);
-      uint32_t getCleanApertureWidthD();
-      void setCleanApertureHeightN(uint32_t newVal);
-      uint32_t getCleanApertureHeightN();
-      void setCleanApertureHeightD(uint32_t newVal);
-      uint32_t getCleanApertureHeightD();
-      void setHorizOffN(uint32_t newVal);
-      uint32_t getHorizOffN();
-      void setHorizOffD(uint32_t newVal);
-      uint32_t getHorizOffD();
-      void setVertOffN(uint32_t newVal);
-      uint32_t getVertOffN();
-      void setVertOffD(uint32_t newVal);
-      uint32_t getVertOffD();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class PASP: public Box{ //PixelAspectRatioBox
-    public:
-      PASP();
-      void setHSpacing(uint32_t newVal);
-      uint32_t getHSpacing();
-      void setVSpacing(uint32_t newVal);
-      uint32_t getVSpacing();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class VisualSampleEntry: public SampleEntry{
-    ///\todo set default values
-    public:
-      VisualSampleEntry();
-      void setCodec(const char* newCodec);
-      void setWidth(uint16_t newWidth);
-      uint16_t getWidth();
-      void setHeight(uint16_t newHeight);
-      uint16_t getHeight();
-      void setHorizResolution (uint32_t newHorizResolution);
-      uint32_t getHorizResolution();
-      void setVertResolution (uint32_t newVertResolution);
-      uint32_t getVertResolution();
-      void setFrameCount(uint16_t newFrameCount);
-      uint16_t getFrameCount();
-      void setCompressorName(std::string newCompressorName);
-      std::string getCompressorName();
-      void setDepth(uint16_t newDepth);
-      uint16_t getDepth();
-      Box & getCLAP();
-      void setCLAP(Box& clap);
-      Box & getPASP();
-      std::string toPrettyVisualString(uint32_t index = 0, std::string = "");
-  };
-  
-  class AudioSampleEntry: public SampleEntry{
-    public:
-      ///\todo set default values
-      AudioSampleEntry();
-      void setCodec(const char* newCodec);
-      void setChannelCount(uint16_t newChannelCount);
-      uint16_t getChannelCount();
-      void setSampleSize(uint16_t newSampleSize);
-      uint16_t getSampleSize();
-      void setPreDefined(uint16_t newPreDefined);
-      uint16_t getPreDefined();
-      void setSampleRate(uint32_t newSampleRate);
-      uint32_t getSampleRate();
-      uint16_t toAACInit();
-      void setCodecBox(Box& newBox);
-      Box & getCodecBox();
-      std::string toPrettyAudioString(uint32_t indent = 0, std::string name = "");
-  };
-  
-  class MP4A: public AudioSampleEntry{
-    public:
-      MP4A();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class AAC: public AudioSampleEntry{
-    public:
-      AAC();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class AVC1: public VisualSampleEntry{
-    public:
-      AVC1();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class H264: public VisualSampleEntry{
-    public:
-      H264();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class STSD: public fullBox{
-    public:
-      STSD(char v = 1, uint32_t f = 0);
-      void setEntryCount (uint32_t newEntryCount);
-      uint32_t getEntryCount();
-      void setEntry(Box & newContent, uint32_t no);
-      Box & getEntry(uint32_t no);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class EDTS: public containerBox{
-    public:
-      EDTS();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class UDTA: public containerBox{
-    public:
-      UDTA();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class STSS: public fullBox{
-    public:
-      STSS(char v = 1, uint32_t f = 0);
-      void setEntryCount(uint32_t newVal);
-      uint32_t getEntryCount();
-      void setSampleNumber(uint32_t newVal, uint32_t index);
-      uint32_t getSampleNumber(uint32_t index);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class META: public containerFullBox{
-    public:
-      META();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-  
-  class ELST: public fullBox{
-    public:
-      ELST();
-      void setSegmentDuration(uint64_t newVal);
-      uint64_t getSegmentDuration();
-      void setMediaTime(uint64_t newVal);
-      uint64_t getMediaTime();
-      void setMediaRateInteger(uint16_t newVal);
-      uint16_t getMediaRateInteger();
-      void setMediaRateFraction(uint16_t newVal);
-      uint16_t getMediaRateFraction();
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-      
-  class UUID: public Box{
-    public:
-      UUID();
-      std::string getUUID();
-      void setUUID(const std::string & uuid_string);
-      void setUUID(const char * raw_uuid);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
-  class UUID_TrackFragmentReference: public UUID{
-    public:
-      UUID_TrackFragmentReference();
-      void setVersion(uint32_t newVersion);
-      uint32_t getVersion();
-      void setFlags(uint32_t newFlags);
-      uint32_t getFlags();
-      void setFragmentCount(uint32_t newCount);
-      uint32_t getFragmentCount();
-      void setTime(size_t num, uint64_t newTime);
-      uint64_t getTime(size_t num);
-      void setDuration(size_t num, uint64_t newDuration);
-      uint64_t getDuration(size_t num);
-      std::string toPrettyString(uint32_t indent = 0);
-  };
-
 }
diff --git a/lib/mp4_adobe.cpp b/lib/mp4_adobe.cpp
new file mode 100644
index 00000000..3cb34ade
--- /dev/null
+++ b/lib/mp4_adobe.cpp
@@ -0,0 +1,928 @@
+#include "mp4_adobe.h"
+
+namespace MP4 {
+  ABST::ABST(){
+    memcpy(data + 4, "abst", 4);
+    setVersion(0);
+    setFlags(0);
+    setBootstrapinfoVersion(0);
+    setProfile(0);
+    setLive(1);
+    setUpdate(0);
+    setTimeScale(1000);
+    setCurrentMediaTime(0);
+    setSmpteTimeCodeOffset(0);
+    std::string empty;
+    setMovieIdentifier(empty);
+    setInt8(0, 30); //set serverentrycount to 0
+    setInt8(0, 31); //set qualityentrycount to 0
+    setDrmData(empty);
+    setMetaData(empty);
+  }
+
+  void ABST::setVersion(char newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  char ABST::getVersion(){
+    return getInt8(0);
+  }
+
+  void ABST::setFlags(uint32_t newFlags){
+    setInt24(newFlags, 1);
+  }
+
+  uint32_t ABST::getFlags(){
+    return getInt24(1);
+  }
+
+  void ABST::setBootstrapinfoVersion(uint32_t newVersion){
+    setInt32(newVersion, 4);
+  }
+
+  uint32_t ABST::getBootstrapinfoVersion(){
+    return getInt32(4);
+  }
+
+  void ABST::setProfile(char newProfile){
+    //profile = bit 1 and 2 of byte 8.
+    setInt8((getInt8(8) & 0x3F) + ((newProfile & 0x03) << 6), 8);
+  }
+
+  char ABST::getProfile(){
+    return (getInt8(8) & 0xC0);
+  }
+  ;
+
+  void ABST::setLive(bool newLive){
+    //live = bit 4 of byte 8.
+    setInt8((getInt8(8) & 0xDF) + (newLive ? 0x10 : 0), 8);
+  }
+
+  bool ABST::getLive(){
+    return (getInt8(8) & 0x10);
+  }
+
+  void ABST::setUpdate(bool newUpdate){
+    //update = bit 5 of byte 8.
+    setInt8((getInt8(8) & 0xEF) + (newUpdate ? 0x08 : 0), 8);
+  }
+
+  bool ABST::getUpdate(){
+    return (getInt8(8) & 0x08);
+  }
+
+  void ABST::setTimeScale(uint32_t newScale){
+    setInt32(newScale, 9);
+  }
+
+  uint32_t ABST::getTimeScale(){
+    return getInt32(9);
+  }
+
+  void ABST::setCurrentMediaTime(uint64_t newTime){
+    setInt64(newTime, 13);
+  }
+
+  uint64_t ABST::getCurrentMediaTime(){
+    return getInt64(13);
+  }
+
+  void ABST::setSmpteTimeCodeOffset(uint64_t newTime){
+    setInt64(newTime, 21);
+  }
+
+  uint64_t ABST::getSmpteTimeCodeOffset(){
+    return getInt64(21);
+  }
+
+  void ABST::setMovieIdentifier(std::string & newIdentifier){
+    setString(newIdentifier, 29);
+  }
+
+  char* ABST::getMovieIdentifier(){
+    return getString(29);
+  }
+
+  uint32_t ABST::getServerEntryCount(){
+    int countLoc = 29 + getStringLen(29) + 1;
+    return getInt8(countLoc);
+  }
+
+  void ABST::setServerEntry(std::string & newEntry, uint32_t no){
+    int countLoc = 29 + getStringLen(29) + 1;
+    int tempLoc = countLoc + 1;
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getInt8(countLoc)){
+      int amount = no + 1 - getInt8(countLoc);
+      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
+        return;
+      };
+      memset(data + payloadOffset + tempLoc, 0, amount);
+      setInt8(no + 1, countLoc); //set new qualityEntryCount
+      tempLoc += no - i;
+    }
+    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
+    setString(newEntry, tempLoc);
+  }
+
+  ///\return Empty string if no > serverEntryCount(), serverEntry[no] otherwise.
+  const char* ABST::getServerEntry(uint32_t no){
+    if (no + 1 > getServerEntryCount()){
+      return "";
+    }
+    int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of first entry
+    for (unsigned int i = 0; i < no; i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getString(tempLoc);
+  }
+
+  uint32_t ABST::getQualityEntryCount(){
+    int countLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      countLoc += getStringLen(countLoc) + 1;
+    }
+    return getInt8(countLoc);
+  }
+
+  void ABST::setQualityEntry(std::string & newEntry, uint32_t no){
+    int countLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      countLoc += getStringLen(countLoc) + 1;
+    }
+    int tempLoc = countLoc + 1;
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getInt8(countLoc)){
+      int amount = no + 1 - getInt8(countLoc);
+      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
+        return;
+      };
+      memset(data + payloadOffset + tempLoc, 0, amount);
+      setInt8(no + 1, countLoc); //set new qualityEntryCount
+      tempLoc += no - i;
+    }
+    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
+    setString(newEntry, tempLoc);
+  }
+
+  const char* ABST::getQualityEntry(uint32_t no){
+    if (no > getQualityEntryCount()){
+      return "";
+    }
+    int tempLoc = 29 + getStringLen(29) + 1 + 1; //position of serverentries;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += 1; //first qualityentry
+    for (unsigned int i = 0; i < no; i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getString(tempLoc);
+  }
+
+  void ABST::setDrmData(std::string newDrm){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    setString(newDrm, tempLoc);
+  }
+
+  char* ABST::getDrmData(){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getString(tempLoc);
+  }
+
+  void ABST::setMetaData(std::string newMetaData){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1;
+    setString(newMetaData, tempLoc);
+  }
+
+  char* ABST::getMetaData(){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1;
+    return getString(tempLoc);
+  }
+
+  uint32_t ABST::getSegmentRunTableCount(){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    return getInt8(tempLoc);
+  }
+
+  void ABST::setSegmentRunTable(ASRT & newSegment, uint32_t no){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    int countLoc = tempLoc;
+    tempLoc++; //skip segmentRuntableCount
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getInt8(countLoc)){
+      int amount = no + 1 - getInt8(countLoc);
+      if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){
+        return;
+      };
+      //set empty erro boxes as contents
+      for (int j = 0; j < amount; ++j){
+        memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
+      }
+      setInt8(no + 1, countLoc); //set new count
+      tempLoc += (no - i) * 8;
+    }
+    //now, tempLoc is at position for string number no, and we have at least an erro box reserved.
+    setBox(newSegment, tempLoc);
+  }
+
+  ASRT & ABST::getSegmentRunTable(uint32_t no){
+    static Box result;
+    if (no > getSegmentRunTableCount()){
+      static Box res;
+      return (ASRT&)res;
+    }
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    tempLoc++; //segmentRuntableCount
+    for (unsigned int i = 0; i < no; ++i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    return (ASRT&)getBox(tempLoc);
+  }
+
+  uint32_t ABST::getFragmentRunTableCount(){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    return getInt8(tempLoc);
+  }
+
+  void ABST::setFragmentRunTable(AFRT & newFragment, uint32_t no){
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    int countLoc = tempLoc;
+    tempLoc++;
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getInt8(countLoc) && i < no; ++i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getInt8(countLoc)){
+      unsigned int amount = no + 1 - getInt8(countLoc);
+      if ( !reserve(payloadOffset + tempLoc, 0, amount * 8)){
+        return;
+      };
+      //set empty erro boxes as contents
+      for (unsigned int j = 0; j < amount; ++j){
+        memcpy(data + payloadOffset + tempLoc + j * 8, "\000\000\000\010erro", 8);
+      }
+      setInt8(no + 1, countLoc); //set new count
+      tempLoc += (no - i) * 8;
+    }
+    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
+    setBox(newFragment, tempLoc);
+  }
+
+  AFRT & ABST::getFragmentRunTable(uint32_t no){
+    static Box result;
+    if (no >= getFragmentRunTableCount()){
+      static Box res;
+      return (AFRT&)res;
+    }
+    uint32_t tempLoc = 29 + getStringLen(29) + 1 + 1;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += getStringLen(tempLoc) + 1; //DrmData
+    tempLoc += getStringLen(tempLoc) + 1; //MetaData
+    for (unsigned int i = getInt8(tempLoc++); i != 0; --i){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    tempLoc++;
+    for (unsigned int i = 0; i < no; i++){
+      tempLoc += getBoxLen(tempLoc);
+    }
+    return (AFRT&)getBox(tempLoc);
+  }
+
+  std::string ABST::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[abst] Bootstrap Info (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "BootstrapinfoVersion " << getBootstrapinfoVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "Profile " << (int)getProfile() << std::endl;
+    if (getLive()){
+      r << std::string(indent + 1, ' ') << "Live" << std::endl;
+    }else{
+      r << std::string(indent + 1, ' ') << "Recorded" << std::endl;
+    }
+    if (getUpdate()){
+      r << std::string(indent + 1, ' ') << "Update" << std::endl;
+    }else{
+      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl;
+    r << std::string(indent + 1, ' ') << "CurrMediaTime " << getCurrentMediaTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "SmpteTimeCodeOffset " << getSmpteTimeCodeOffset() << std::endl;
+    r << std::string(indent + 1, ' ') << "MovieIdentifier " << getMovieIdentifier() << std::endl;
+    r << std::string(indent + 1, ' ') << "ServerEntryTable (" << getServerEntryCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getServerEntryCount(); i++){
+      r << std::string(indent + 2, ' ') << i << ": " << getServerEntry(i) << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "DrmData " << getDrmData() << std::endl;
+    r << std::string(indent + 1, ' ') << "MetaData " << getMetaData() << std::endl;
+    r << std::string(indent + 1, ' ') << "SegmentRunTableEntries (" << getSegmentRunTableCount() << ")" << std::endl;
+    for (uint32_t i = 0; i < getSegmentRunTableCount(); i++){
+      r << ((Box)getSegmentRunTable(i)).toPrettyString(indent + 2);
+    }
+    r << std::string(indent + 1, ' ') + "FragmentRunTableEntries (" << getFragmentRunTableCount() << ")" << std::endl;
+    for (uint32_t i = 0; i < getFragmentRunTableCount(); i++){
+      r << ((Box)getFragmentRunTable(i)).toPrettyString(indent + 2);
+    }
+    return r.str();
+  }
+
+  AFRT::AFRT(){
+    memcpy(data + 4, "afrt", 4);
+    setVersion(0);
+    setUpdate(0);
+    setTimeScale(1000);
+  }
+
+  void AFRT::setVersion(char newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  uint32_t AFRT::getVersion(){
+    return getInt8(0);
+  }
+
+  void AFRT::setUpdate(uint32_t newUpdate){
+    setInt24(newUpdate, 1);
+  }
+
+  uint32_t AFRT::getUpdate(){
+    return getInt24(1);
+  }
+
+  void AFRT::setTimeScale(uint32_t newScale){
+    setInt32(newScale, 4);
+  }
+
+  uint32_t AFRT::getTimeScale(){
+    return getInt32(4);
+  }
+
+  uint32_t AFRT::getQualityEntryCount(){
+    return getInt8(8);
+  }
+
+  void AFRT::setQualityEntry(std::string & newEntry, uint32_t no){
+    int countLoc = 8;
+    int tempLoc = countLoc + 1;
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getQualityEntryCount() && i < no; ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getQualityEntryCount()){
+      int amount = no + 1 - getQualityEntryCount();
+      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
+        return;
+      };
+      memset(data + payloadOffset + tempLoc, 0, amount);
+      setInt8(no + 1, countLoc); //set new qualityEntryCount
+      tempLoc += no - i;
+    }
+    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
+    setString(newEntry, tempLoc);
+  }
+
+  const char* AFRT::getQualityEntry(uint32_t no){
+    if (no + 1 > getQualityEntryCount()){
+      return "";
+    }
+    int tempLoc = 9; //position of first quality entry
+    for (unsigned int i = 0; i < no; i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getString(tempLoc);
+  }
+
+  uint32_t AFRT::getFragmentRunCount(){
+    int tempLoc = 9;
+    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getInt32(tempLoc);
+  }
+
+  void AFRT::setFragmentRun(afrt_runtable newRun, uint32_t no){
+    int tempLoc = 9;
+    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    int countLoc = tempLoc;
+    tempLoc += 4;
+    for (unsigned int i = 0; i < no; i++){
+      if (i + 1 > getInt32(countLoc)){
+        setInt32(0, tempLoc);
+        setInt64(0, tempLoc + 4);
+        setInt32(1, tempLoc + 12);
+      }
+      if (getInt32(tempLoc + 12) == 0){
+        tempLoc += 17;
+      }else{
+        tempLoc += 16;
+      }
+    }
+    setInt32(newRun.firstFragment, tempLoc);
+    setInt64(newRun.firstTimestamp, tempLoc + 4);
+    setInt32(newRun.duration, tempLoc + 12);
+    if (newRun.duration == 0){
+      setInt8(newRun.discontinuity, tempLoc + 16);
+    }
+    if (getInt32(countLoc) < no + 1){
+      setInt32(no + 1, countLoc);
+    }
+  }
+
+  afrt_runtable AFRT::getFragmentRun(uint32_t no){
+    afrt_runtable res;
+    if (no > getFragmentRunCount()){
+      return res;
+    }
+    int tempLoc = 9;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += 4;
+    for (unsigned int i = 0; i < no; i++){
+      if (getInt32(tempLoc + 12) == 0){
+        tempLoc += 17;
+      }else{
+        tempLoc += 16;
+      }
+    }
+    res.firstFragment = getInt32(tempLoc);
+    res.firstTimestamp = getInt64(tempLoc + 4);
+    res.duration = getInt32(tempLoc + 12);
+    if (res.duration){
+      res.discontinuity = getInt8(tempLoc + 16);
+    }else{
+      res.discontinuity = 0;
+    }
+    return res;
+  }
+
+  std::string AFRT::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[afrt] Fragment Run Table (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << (int)getVersion() << std::endl;
+    if (getUpdate()){
+      r << std::string(indent + 1, ' ') << "Update" << std::endl;
+    }else{
+      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "Timescale " << getTimeScale() << std::endl;
+    r << std::string(indent + 1, ' ') << "QualitySegmentUrlModifiers (" << getQualityEntryCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "FragmentRunEntryTable (" << getFragmentRunCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getFragmentRunCount(); i++){
+      afrt_runtable myRun = getFragmentRun(i);
+      if (myRun.duration){
+        r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
+            << "s, " << ((double)myRun.duration / (double)getTimeScale()) << "s per fragment." << std::endl;
+      }else{
+        r << std::string(indent + 2, ' ') << i << ": " << myRun.firstFragment << " is at " << ((double)myRun.firstTimestamp / (double)getTimeScale())
+            << "s, discontinuity type " << myRun.discontinuity << std::endl;
+      }
+    }
+    return r.str();
+  }
+
+  ASRT::ASRT(){
+    memcpy(data + 4, "asrt", 4);
+    setVersion(0);
+    setUpdate(0);
+  }
+
+  void ASRT::setVersion(char newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  uint32_t ASRT::getVersion(){
+    return getInt8(0);
+  }
+
+  void ASRT::setUpdate(uint32_t newUpdate){
+    setInt24(newUpdate, 1);
+  }
+
+  uint32_t ASRT::getUpdate(){
+    return getInt24(1);
+  }
+
+  uint32_t ASRT::getQualityEntryCount(){
+    return getInt8(4);
+  }
+
+  void ASRT::setQualityEntry(std::string & newEntry, uint32_t no){
+    int countLoc = 4;
+    int tempLoc = countLoc + 1;
+    //attempt to reach the wanted position
+    unsigned int i;
+    for (i = 0; i < getQualityEntryCount() && i < no; ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    //we are now either at the end, or at the right position
+    //let's reserve any unreserved space...
+    if (no + 1 > getQualityEntryCount()){
+      int amount = no + 1 - getQualityEntryCount();
+      if ( !reserve(payloadOffset + tempLoc, 0, amount)){
+        return;
+      };
+      memset(data + payloadOffset + tempLoc, 0, amount);
+      setInt8(no + 1, countLoc); //set new qualityEntryCount
+      tempLoc += no - i;
+    }
+    //now, tempLoc is at position for string number no, and we have at least 1 byte reserved.
+    setString(newEntry, tempLoc);
+  }
+
+  const char* ASRT::getQualityEntry(uint32_t no){
+    if (no > getQualityEntryCount()){
+      return "";
+    }
+    int tempLoc = 5; //position of qualityentry count;
+    for (unsigned int i = 0; i < no; i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getString(tempLoc);
+  }
+
+  uint32_t ASRT::getSegmentRunEntryCount(){
+    int tempLoc = 5; //position of qualityentry count;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    return getInt32(tempLoc);
+  }
+
+  void ASRT::setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no){
+    int tempLoc = 5; //position of qualityentry count;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    int countLoc = tempLoc;
+    tempLoc += 4 + no * 8;
+    if (no + 1 > getInt32(countLoc)){
+      setInt32(no + 1, countLoc); //set new qualityEntryCount
+    }
+    setInt32(firstSegment, tempLoc);
+    setInt32(fragmentsPerSegment, tempLoc + 4);
+  }
+
+  asrt_runtable ASRT::getSegmentRun(uint32_t no){
+    asrt_runtable res;
+    if (no >= getSegmentRunEntryCount()){
+      return res;
+    }
+    int tempLoc = 5; //position of qualityentry count;
+    for (unsigned int i = 0; i < getQualityEntryCount(); ++i){
+      tempLoc += getStringLen(tempLoc) + 1;
+    }
+    tempLoc += 4 + 8 * no;
+    res.firstSegment = getInt32(tempLoc);
+    res.fragmentsPerSegment = getInt32(tempLoc + 4);
+    return res;
+  }
+
+  std::string ASRT::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[asrt] Segment Run Table (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl;
+    if (getUpdate()){
+      r << std::string(indent + 1, ' ') << "Update" << std::endl;
+    }else{
+      r << std::string(indent + 1, ' ') << "Replacement or new table" << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "QualityEntryTable (" << getQualityEntryCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getQualityEntryCount(); i++){
+      r << std::string(indent + 2, ' ') << i << ": " << getQualityEntry(i) << std::endl;
+    }
+    r << std::string(indent + 1, ' ') << "SegmentRunEntryTable (" << getSegmentRunEntryCount() << ")" << std::endl;
+    for (unsigned int i = 0; i < getSegmentRunEntryCount(); i++){
+      r << std::string(indent + 2, ' ') << i << ": First=" << getSegmentRun(i).firstSegment << ", FragmentsPerSegment="
+          << getSegmentRun(i).fragmentsPerSegment << std::endl;
+    }
+    return r.str();
+  }
+  AFRA::AFRA(){
+    memcpy(data + 4, "afra", 4);
+    setInt32(0, 9); //entrycount = 0
+    setFlags(0);
+  }
+
+  void AFRA::setVersion(uint32_t newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  uint32_t AFRA::getVersion(){
+    return getInt8(0);
+  }
+
+  void AFRA::setFlags(uint32_t newFlags){
+    setInt24(newFlags, 1);
+  }
+
+  uint32_t AFRA::getFlags(){
+    return getInt24(1);
+  }
+
+  void AFRA::setLongIDs(bool newVal){
+    if (newVal){
+      setInt8((getInt8(4) & 0x7F) + 0x80, 4);
+    }else{
+      setInt8((getInt8(4) & 0x7F), 4);
+    }
+  }
+
+  bool AFRA::getLongIDs(){
+    return getInt8(4) & 0x80;
+  }
+
+  void AFRA::setLongOffsets(bool newVal){
+    if (newVal){
+      setInt8((getInt8(4) & 0xBF) + 0x40, 4);
+    }else{
+      setInt8((getInt8(4) & 0xBF), 4);
+    }
+  }
+
+  bool AFRA::getLongOffsets(){
+    return getInt8(4) & 0x40;
+  }
+
+  void AFRA::setGlobalEntries(bool newVal){
+    if (newVal){
+      setInt8((getInt8(4) & 0xDF) + 0x20, 4);
+    }else{
+      setInt8((getInt8(4) & 0xDF), 4);
+    }
+  }
+
+  bool AFRA::getGlobalEntries(){
+    return getInt8(4) & 0x20;
+  }
+
+  void AFRA::setTimeScale(uint32_t newVal){
+    setInt32(newVal, 5);
+  }
+
+  uint32_t AFRA::getTimeScale(){
+    return getInt32(5);
+  }
+
+  uint32_t AFRA::getEntryCount(){
+    return getInt32(9);
+  }
+
+  void AFRA::setEntry(afraentry newEntry, uint32_t no){
+    int entrysize = 12;
+    if (getLongOffsets()){
+      entrysize = 16;
+    }
+    setInt64(newEntry.time, 13 + entrysize * no);
+    if (getLongOffsets()){
+      setInt64(newEntry.offset, 21 + entrysize * no);
+    }else{
+      setInt32(newEntry.offset, 21 + entrysize * no);
+    }
+    if (no + 1 > getEntryCount()){
+      setInt32(no + 1, 9);
+    }
+  }
+
+  afraentry AFRA::getEntry(uint32_t no){
+    afraentry ret;
+    int entrysize = 12;
+    if (getLongOffsets()){
+      entrysize = 16;
+    }
+    ret.time = getInt64(13 + entrysize * no);
+    if (getLongOffsets()){
+      ret.offset = getInt64(21 + entrysize * no);
+    }else{
+      ret.offset = getInt32(21 + entrysize * no);
+    }
+    return ret;
+  }
+
+  uint32_t AFRA::getGlobalEntryCount(){
+    if ( !getGlobalEntries()){
+      return 0;
+    }
+    int entrysize = 12;
+    if (getLongOffsets()){
+      entrysize = 16;
+    }
+    return getInt32(13 + entrysize * getEntryCount());
+  }
+
+  void AFRA::setGlobalEntry(globalafraentry newEntry, uint32_t no){
+    int offset = 13 + 12 * getEntryCount() + 4;
+    if (getLongOffsets()){
+      offset = 13 + 16 * getEntryCount() + 4;
+    }
+    int entrysize = 20;
+    if (getLongIDs()){
+      entrysize += 4;
+    }
+    if (getLongOffsets()){
+      entrysize += 8;
+    }
+
+    setInt64(newEntry.time, offset + entrysize * no);
+    if (getLongIDs()){
+      setInt32(newEntry.segment, offset + entrysize * no + 8);
+      setInt32(newEntry.fragment, offset + entrysize * no + 12);
+    }else{
+      setInt16(newEntry.segment, offset + entrysize * no + 8);
+      setInt16(newEntry.fragment, offset + entrysize * no + 10);
+    }
+    if (getLongOffsets()){
+      setInt64(newEntry.afraoffset, offset + entrysize * no + entrysize - 16);
+      setInt64(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 8);
+    }else{
+      setInt32(newEntry.afraoffset, offset + entrysize * no + entrysize - 8);
+      setInt32(newEntry.offsetfromafra, offset + entrysize * no + entrysize - 4);
+    }
+
+    if (getInt32(offset - 4) < no + 1){
+      setInt32(no + 1, offset - 4);
+    }
+  }
+
+  globalafraentry AFRA::getGlobalEntry(uint32_t no){
+    globalafraentry ret;
+    int offset = 13 + 12 * getEntryCount() + 4;
+    if (getLongOffsets()){
+      offset = 13 + 16 * getEntryCount() + 4;
+    }
+    int entrysize = 20;
+    if (getLongIDs()){
+      entrysize += 4;
+    }
+    if (getLongOffsets()){
+      entrysize += 8;
+    }
+
+    ret.time = getInt64(offset + entrysize * no);
+    if (getLongIDs()){
+      ret.segment = getInt32(offset + entrysize * no + 8);
+      ret.fragment = getInt32(offset + entrysize * no + 12);
+    }else{
+      ret.segment = getInt16(offset + entrysize * no + 8);
+      ret.fragment = getInt16(offset + entrysize * no + 10);
+    }
+    if (getLongOffsets()){
+      ret.afraoffset = getInt64(offset + entrysize * no + entrysize - 16);
+      ret.offsetfromafra = getInt64(offset + entrysize * no + entrysize - 8);
+    }else{
+      ret.afraoffset = getInt32(offset + entrysize * no + entrysize - 8);
+      ret.offsetfromafra = getInt32(offset + entrysize * no + entrysize - 4);
+    }
+    return ret;
+  }
+
+  std::string AFRA::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[afra] Fragment Random Access (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << getVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "Flags " << getFlags() << std::endl;
+    r << std::string(indent + 1, ' ') << "Long IDs " << getLongIDs() << std::endl;
+    r << std::string(indent + 1, ' ') << "Long Offsets " << getLongOffsets() << std::endl;
+    r << std::string(indent + 1, ' ') << "Global Entries " << getGlobalEntries() << std::endl;
+    r << std::string(indent + 1, ' ') << "TimeScale " << getTimeScale() << std::endl;
+
+    uint32_t count = getEntryCount();
+    r << std::string(indent + 1, ' ') << "Entries (" << count << ") " << std::endl;
+    for (uint32_t i = 0; i < count; ++i){
+      afraentry tmpent = getEntry(i);
+      r << std::string(indent + 1, ' ') << i << ": Time " << tmpent.time << ", Offset " << tmpent.offset << std::endl;
+    }
+
+    if (getGlobalEntries()){
+      count = getGlobalEntryCount();
+      r << std::string(indent + 1, ' ') << "Global Entries (" << count << ") " << std::endl;
+      for (uint32_t i = 0; i < count; ++i){
+        globalafraentry tmpent = getGlobalEntry(i);
+        r << std::string(indent + 1, ' ') << i << ": T " << tmpent.time << ", S" << tmpent.segment << "F" << tmpent.fragment << ", "
+            << tmpent.afraoffset << "/" << tmpent.offsetfromafra << std::endl;
+      }
+    }
+    return r.str();
+  }
+}
diff --git a/lib/mp4_adobe.h b/lib/mp4_adobe.h
new file mode 100644
index 00000000..3ab14fcc
--- /dev/null
+++ b/lib/mp4_adobe.h
@@ -0,0 +1,139 @@
+#pragma once
+#include "mp4.h"
+#include <stdint.h>
+
+namespace MP4 {
+  //class Box;
+  
+  struct afrt_runtable{
+      uint32_t firstFragment;
+      uint64_t firstTimestamp;
+      uint32_t duration;
+      uint32_t discontinuity;
+  };
+  //fragmentRun
+
+  /// AFRT Box class
+  class AFRT: public Box{
+    public:
+      AFRT();
+      void setVersion(char newVersion);
+      uint32_t getVersion();
+      void setUpdate(uint32_t newUpdate);
+      uint32_t getUpdate();
+      void setTimeScale(uint32_t newScale);
+      uint32_t getTimeScale();
+      uint32_t getQualityEntryCount();
+      void setQualityEntry(std::string & newQuality, uint32_t no);
+      const char * getQualityEntry(uint32_t no);
+      uint32_t getFragmentRunCount();
+      void setFragmentRun(afrt_runtable newRun, uint32_t no);
+      afrt_runtable getFragmentRun(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  //AFRT Box
+
+  struct asrt_runtable{
+      uint32_t firstSegment;
+      uint32_t fragmentsPerSegment;
+  };
+
+  /// ASRT Box class
+  class ASRT: public Box{
+    public:
+      ASRT();
+      void setVersion(char newVersion);
+      uint32_t getVersion();
+      void setUpdate(uint32_t newUpdate);
+      uint32_t getUpdate();
+      uint32_t getQualityEntryCount();
+      void setQualityEntry(std::string & newQuality, uint32_t no);
+      const char* getQualityEntry(uint32_t no);
+      uint32_t getSegmentRunEntryCount();
+      void setSegmentRun(uint32_t firstSegment, uint32_t fragmentsPerSegment, uint32_t no);
+      asrt_runtable getSegmentRun(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  //ASRT Box
+
+  /// ABST Box class
+  class ABST: public Box{
+    public:
+      ABST();
+      void setVersion(char newVersion);
+      char getVersion();
+      void setFlags(uint32_t newFlags);
+      uint32_t getFlags();
+      void setBootstrapinfoVersion(uint32_t newVersion);
+      uint32_t getBootstrapinfoVersion();
+      void setProfile(char newProfile);
+      char getProfile();
+      void setLive(bool newLive);
+      bool getLive();
+      void setUpdate(bool newUpdate);
+      bool getUpdate();
+      void setTimeScale(uint32_t newTimeScale);
+      uint32_t getTimeScale();
+      void setCurrentMediaTime(uint64_t newTime);
+      uint64_t getCurrentMediaTime();
+      void setSmpteTimeCodeOffset(uint64_t newTime);
+      uint64_t getSmpteTimeCodeOffset();
+      void setMovieIdentifier(std::string & newIdentifier);
+      char * getMovieIdentifier();
+      uint32_t getServerEntryCount();
+      void setServerEntry(std::string & entry, uint32_t no);
+      const char * getServerEntry(uint32_t no);
+      uint32_t getQualityEntryCount();
+      void setQualityEntry(std::string & entry, uint32_t no);
+      const char * getQualityEntry(uint32_t no);
+      void setDrmData(std::string newDrm);
+      char * getDrmData();
+      void setMetaData(std::string newMetaData);
+      char * getMetaData();
+      uint32_t getSegmentRunTableCount();
+      void setSegmentRunTable(ASRT & table, uint32_t no);
+      ASRT & getSegmentRunTable(uint32_t no);
+      uint32_t getFragmentRunTableCount();
+      void setFragmentRunTable(AFRT & table, uint32_t no);
+      AFRT & getFragmentRunTable(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  //ABST Box
+
+  struct afraentry{
+      uint64_t time;
+      uint64_t offset;
+  };
+  struct globalafraentry{
+      uint64_t time;
+      uint32_t segment;
+      uint32_t fragment;
+      uint64_t afraoffset;
+      uint64_t offsetfromafra;
+  };
+  class AFRA: public Box{
+    public:
+      AFRA();
+      void setVersion(uint32_t newVersion);
+      uint32_t getVersion();
+      void setFlags(uint32_t newFlags);
+      uint32_t getFlags();
+      void setLongIDs(bool newVal);
+      bool getLongIDs();
+      void setLongOffsets(bool newVal);
+      bool getLongOffsets();
+      void setGlobalEntries(bool newVal);
+      bool getGlobalEntries();
+      void setTimeScale(uint32_t newVal);
+      uint32_t getTimeScale();
+      uint32_t getEntryCount();
+      void setEntry(afraentry newEntry, uint32_t no);
+      afraentry getEntry(uint32_t no);
+      uint32_t getGlobalEntryCount();
+      void setGlobalEntry(globalafraentry newEntry, uint32_t no);
+      globalafraentry getGlobalEntry(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+}
+
diff --git a/lib/mp4_conv.cpp b/lib/mp4_conv.cpp
index 7810e6f4..4b249359 100644
--- a/lib/mp4_conv.cpp
+++ b/lib/mp4_conv.cpp
@@ -1,4 +1,4 @@
-#include "mp4.h"
+#include "mp4_generic.h"
 #include <sstream>
 
 namespace MP4{
@@ -17,21 +17,22 @@ namespace MP4{
     
     uint64_t mdatSize = 0;
     //moov box
-    MP4::MOOV moovBox;
+    MP4::MOOV moovBox;{
+      //calculating longest duration
+      long long int fileDuration = 0;
+      /// \todo lastms and firstms fix
+      for ( std::map<int,DTSC::Track>::iterator trackIt = metaData.tracks.begin(); trackIt != metaData.tracks.end(); trackIt ++) {
+        if (trackIt->second.lastms - trackIt->second.firstms > fileDuration){
+          fileDuration =  trackIt->second.lastms - trackIt->second.firstms;
+        }
+      }
+      //MP4::MVHD mvhdBox(fileDuration);
       MP4::MVHD mvhdBox;
       mvhdBox.setVersion(0);
       mvhdBox.setCreationTime(0);
       mvhdBox.setModificationTime(0);
       mvhdBox.setTimeScale(1000);
       mvhdBox.setRate(0x10000);
-      //calculating longest duration
-      int fileDuration = 0;
-      ///\  odo lastms and firstms fixen
-      for ( std::map<int,DTSC::Track>::iterator trackIt = metaData.tracks.begin(); trackIt != metaData.tracks.end(); trackIt ++) {
-        if (trackIt->second.lastms - trackIt->second.firstms > fileDuration){
-          fileDuration =  trackIt->second.lastms - trackIt->second.firstms;
-        }
-      }
       mvhdBox.setDuration(fileDuration);
       mvhdBox.setTrackID(0);
       mvhdBox.setVolume(256);
@@ -45,50 +46,11 @@ namespace MP4{
       mvhdBox.setMatrix(0,7);
       mvhdBox.setMatrix(0x40000000,8);
       moovBox.setContent(mvhdBox, 0);
-      
+    }
+    {//start arbitrary track addition for header
+      int boxOffset = 1;
       bool seenAudio = false;
       bool seenVideo = false;
-      
-      //calculate interleaving
-      //putting all metadata in a huge, auto-sorting vector 'keyParts'
-      //sort by time on keyframes for interleaving
-      keyParts.clear();
-      for ( std::map<int,DTSC::Track>::iterator trackIt = metaData.tracks.begin(); trackIt != metaData.tracks.end(); trackIt ++) {
-        if (trackIt->second.codec != "AAC" && trackIt->second.codec != "H264"){continue;}
-        if (trackIt->second.type == "audio"){
-          if (seenAudio){continue;}
-          seenAudio = true;
-        }
-        if (trackIt->second.type == "video"){
-          if (seenVideo){continue;}
-          seenVideo = true;
-        }
-        if (trackIt->first>0){
-          int partItNumber = 0;
-          for ( std::deque< DTSC::Key>::iterator keyIt = trackIt->second.keys.begin(); keyIt != trackIt->second.keys.end(); keyIt ++) {
-            keyPart temp;
-            temp.trackID = trackIt->second.trackID;
-            temp.time = keyIt->getTime();//timeplaats van keyframe
-            temp.len = keyIt->getLength();//duration van keyframe
-            temp.parts = std::deque<DTSC::Part> (trackIt->second.parts.begin() + partItNumber,trackIt->second.parts.begin() + partItNumber + keyIt->getParts() );//array met bytegrootte van elke aparte part
-            //calculate total size of parts
-            int tempSize = 0;
-            for (unsigned int di = 0; di < temp.parts.size(); di++){
-              tempSize += temp.parts[di].getSize();
-            }
-            temp.size = tempSize;//bytegrootte van keyframe (alle parts bij elkaar)
-            temp.partsize = keyIt->getParts();//amount of parts in this keyframe
-            
-            keyParts.insert(temp);
-            partItNumber += keyIt->getParts();
-          }
-        }
-      }
-      
-      //start arbitrary track addition for header
-      int boxOffset = 1;
-      seenAudio = false;
-      seenVideo = false;
       for ( std::map<int,DTSC::Track>::iterator it = metaData.tracks.begin(); it != metaData.tracks.end(); it ++) {
         if (it->second.codec != "AAC" && it->second.codec != "H264"){continue;}
         if (it->second.type == "audio"){
@@ -102,11 +64,13 @@ namespace MP4{
         if (it->first > 0){
           int timescale = 0;
           MP4::TRAK trakBox;
+          {
+            {
             MP4::TKHD tkhdBox;
             tkhdBox.setVersion(0);
             tkhdBox.setFlags(15);
             tkhdBox.setTrackID(it->second.trackID);
-            ///\  odo duration firstms and lastms fix
+            /// \todo duration firstms and lastms fix
             tkhdBox.setDuration(it->second.lastms + it->second.firstms);
             
             if (it->second.type == "video"){
@@ -127,41 +91,40 @@ namespace MP4{
             tkhdBox.setMatrix(0,7);
             tkhdBox.setMatrix(0x40000000,8);
             trakBox.setContent(tkhdBox, 0);
-            
+            }{
             MP4::MDIA mdiaBox;
+              {
               MP4::MDHD mdhdBox(0);/// \todo fix constructor mdhd in lib
               mdhdBox.setCreationTime(0);
               mdhdBox.setModificationTime(0);
               //Calculating media time based on sampledelta. Probably cheating, but it works...
-              int tmpParts = 0;
-              for (std::deque< DTSC::Key>::iterator tmpIt = it->second.keys.begin(); tmpIt != it->second.keys.end(); tmpIt ++) {
-                tmpParts += tmpIt->getParts();
-              }
-              timescale = ((double)(42 * tmpParts) / (it->second.lastms + it->second.firstms)) *  1000;
+              timescale = ((double)(42 * it->second.parts.size() ) / (it->second.lastms + it->second.firstms)) *  1000;
               mdhdBox.setTimeScale(timescale);
-              ///\  odo fix lastms, firstms
+              /// \todo fix lastms, firstms
               mdhdBox.setDuration((it->second.lastms + it->second.firstms) * ((double)timescale / 1000));
               mdiaBox.setContent(mdhdBox, 0);
-              
-              std::string tmpStr = it->second.type;
+              }//MDHD box
+              {
               MP4::HDLR hdlrBox;/// \todo fix constructor hdlr in lib
-              if (tmpStr == "video"){
+              if (it->second.type == "video"){
                 hdlrBox.setHandlerType(0x76696465);//vide
-              }else if (tmpStr == "audio"){
+              }else if (it->second.type == "audio"){
                 hdlrBox.setHandlerType(0x736F756E);//soun
               }
               hdlrBox.setName(it->second.getIdentifier());
               mdiaBox.setContent(hdlrBox, 1);
-              
+              }//hdlr box
+              {
               MP4::MINF minfBox;
-                if (tmpStr == "video"){
+                if (it->second.type== "video"){
                   MP4::VMHD vmhdBox;
                   vmhdBox.setFlags(1);
                   minfBox.setContent(vmhdBox,0);
-                }else if (tmpStr == "audio"){
+                }else if (it->second.type == "audio"){
                   MP4::SMHD smhdBox;
                   minfBox.setContent(smhdBox,0);
-                }
+                }//type box
+                {
                 MP4::DINF dinfBox;
                   MP4::DREF drefBox;/// \todo fix constructor dref in lib
                     drefBox.setVersion(0);
@@ -170,14 +133,15 @@ namespace MP4{
                     drefBox.setDataEntry(urlBox,0);
                   dinfBox.setContent(drefBox,0);
                 minfBox.setContent(dinfBox,1);
-                
+                }//dinf box
+                {
                 MP4::STBL stblBox;
+                  {
                   MP4::STSD stsdBox;
                     stsdBox.setVersion(0);
-                    if (tmpStr == "video"){//boxname = codec
+                    if (it->second.type == "video"){//boxname = codec
                       MP4::VisualSampleEntry vse;
-                      std::string tmpStr2 = it->second.codec;
-                      if (tmpStr2 == "H264"){
+                      if (it->second.codec == "H264"){
                         vse.setCodec("avc1");
                       }
                       vse.setDataReferenceIndex(1);
@@ -187,21 +151,26 @@ namespace MP4{
                         avccBox.setPayload(it->second.init);
                         vse.setCLAP(avccBox);
                       stsdBox.setEntry(vse,0);
-                    }else if(tmpStr == "audio"){//boxname = codec
+                    }else if(it->second.type == "audio"){//boxname = codec
                       MP4::AudioSampleEntry ase;
-                      std::string tmpStr2 = it->second.codec;
-                      if (tmpStr2 == "AAC"){
+                      if (it->second.codec == "AAC"){
                         ase.setCodec("mp4a");
                         ase.setDataReferenceIndex(1);
                       }
                       ase.setSampleRate(it->second.rate);
                       ase.setChannelCount(it->second.channels);
                       ase.setSampleSize(it->second.size);
+                        //MP4::ESDS esdsBox(it->second.init, it->second.bps);
                         MP4::ESDS esdsBox;
+
+                        //outputting these values first, so malloc isn't called as often.
+                        esdsBox.setESHeaderStartCodes(it->second.init);
+                        esdsBox.setSLValue(2);
+
                         esdsBox.setESDescriptorTypeLength(32+it->second.init.size());
                         esdsBox.setESID(2);
                         esdsBox.setStreamPriority(0);
-                        esdsBox.setDecoderConfigDescriptorTypeLength(18+it->second.init.size());
+                        esdsBox.setDecoderConfigDescriptorTypeLength(18 + it->second.init.size());
                         esdsBox.setByteObjectTypeID(0x40);
                         esdsBox.setStreamType(5);
                         esdsBox.setReservedFlag(1);
@@ -209,26 +178,25 @@ namespace MP4{
                         esdsBox.setMaximumBitRate(10000000);
                         esdsBox.setAverageBitRate(it->second.bps * 8);
                         esdsBox.setConfigDescriptorTypeLength(5);
-                        esdsBox.setESHeaderStartCodes(it->second.init);
                         esdsBox.setSLConfigDescriptorTypeTag(0x6);
                         esdsBox.setSLConfigExtendedDescriptorTypeTag(0x808080);
                         esdsBox.setSLDescriptorTypeLength(1);
-                        esdsBox.setSLValue(2);
                         ase.setCodecBox(esdsBox);
                       stsdBox.setEntry(ase,0);
                     }
                   stblBox.setContent(stsdBox,0);
-                  
-                  /// \ odo update following stts lines
+                  }//stsd box
+                  /// \todo update following stts lines
+                  {
                   MP4::STTS sttsBox;//current version probably causes problems
                     sttsBox.setVersion(0);
                     MP4::STTSEntry newEntry;
-                    newEntry.sampleCount = tmpParts;
+                    newEntry.sampleCount = it->second.parts.size();
                     //42, Used as magic number for timescale calculation
                     newEntry.sampleDelta = 42;
                     sttsBox.setSTTSEntry(newEntry, 0);
                   stblBox.setContent(sttsBox,1);
-                  
+                  }//stts box
                   if (it->second.type == "video"){
                     //STSS Box here
                     MP4::STSS stssBox;
@@ -241,21 +209,21 @@ namespace MP4{
                         tmpItCount ++;
                       }
                     stblBox.setContent(stssBox,2);
-                  }
+                  }//stss box
 
                   int offset = (it->second.type == "video");
-
-                  
+                  {
                   MP4::STSC stscBox;
                   stscBox.setVersion(0);
-                  uint32_t total = 0;
                   MP4::STSCEntry stscEntry;
                   stscEntry.firstChunk = 1;
                   stscEntry.samplesPerChunk = 1;
                   stscEntry.sampleDescriptionIndex = 1;
                   stscBox.setSTSCEntry(stscEntry, 0);
                   stblBox.setContent(stscBox,2 + offset);
-
+                  }//stsc box
+                  {
+                  uint32_t total = 0;
                   MP4::STSZ stszBox;
                   stszBox.setVersion(0);
                   total = 0;
@@ -264,49 +232,41 @@ namespace MP4{
                     total++;
                   }
                   stblBox.setContent(stszBox,3 + offset);
-                    
+                  }//stsz box
+                  //add STCO boxes here
+                  {
                   MP4::STCO stcoBox;
                   stcoBox.setVersion(1);
-                  total = 0;
-                  long long unsigned int totalByteOffset = 0;
-                  //Inserting wrong values on purpose here, will be fixed later.
-                  //Current values are actual byte offset without header-sized offset
-                  for (std::set<keyPart>::iterator i = keyParts.begin(); i != keyParts.end(); i++){//for all keypart size
-                    if(i->trackID == it->second.trackID){//if keypart is of current trackID
-                      std::deque<DTSC::Part> tempArr = i->parts;
-                      for (unsigned int o = 0; o < tempArr.size(); o++){//add all parts to STCO
-                        stcoBox.setChunkOffset(totalByteOffset, total);
-                        total++;
-                        totalByteOffset += tempArr[o].getSize();
-                      }
-                    }else{
-                      totalByteOffset += i->size;
-                    }
+                  //Inserting empty values on purpose here, will be fixed later.
+                  if (it->second.parts.size() != 0){
+                    stcoBox.setChunkOffset(0, it->second.parts.size() - 1);//this inserts all empty entries at once
                   }
-                  //calculating the offset where the STCO box will be in the main MOOV box
-                  //needed for probable optimise
-                  mdatSize = totalByteOffset;
-                  
                   stblBox.setContent(stcoBox,4 + offset);
+                  }//stco box
                 minfBox.setContent(stblBox,2);
+                }//stbl box
               mdiaBox.setContent(minfBox, 2);
+              }//minf box
             trakBox.setContent(mdiaBox, 1);
+            }
+          }//trak Box
           moovBox.setContent(trakBox, boxOffset);
           boxOffset++;
         }
       }
-    //end arbitrary
+    }//end arbitrary track addition
     //initial offset length ftyp, length moov + 8
     unsigned long long int byteOffset = ftypBox.boxedSize() + moovBox.boxedSize() + 8;
-    //update all STCO
-    //for tracks
+    //update all STCO from the following map;
+    std::map <int, MP4::STCO> checkStcoBoxes;
+    //for all tracks
     for (unsigned int i = 1; i < moovBox.getContentCount(); i++){
       //10 lines to get the STCO box.
       MP4::TRAK checkTrakBox;
       MP4::MDIA checkMdiaBox;
       MP4::MINF checkMinfBox;
       MP4::STBL checkStblBox;
-      MP4::STCO checkStcoBox;
+      //MP4::STCO checkStcoBox;
       checkTrakBox = ((MP4::TRAK&)moovBox.getContent(i));
       for (unsigned int j = 0; j < checkTrakBox.getContentCount(); j++){
         if (checkTrakBox.getContent(j).isType("mdia")){
@@ -328,15 +288,46 @@ namespace MP4{
       }
       for (unsigned int j = 0; j < checkStblBox.getContentCount(); j++){
         if (checkStblBox.getContent(j).isType("stco")){
-          checkStcoBox = ((MP4::STCO&)checkStblBox.getContent(j));
+          checkStcoBoxes.insert( std::pair<int, MP4::STCO>(i, ((MP4::STCO&)checkStblBox.getContent(j)) ));
           break;
         }
       }
-      //got the STCO box, fixing values with MP4 header offset
-      for (unsigned int j = 0; j < checkStcoBox.getEntryCount(); j++){
-        checkStcoBox.setChunkOffset(checkStcoBox.getChunkOffset(j) + byteOffset, j);
-      }
     }
+    //inserting right values in the STCO box header
+    //total = 0;
+    long long unsigned int totalByteOffset = 0;
+    //Current values are actual byte offset without header-sized offset
+    std::set <keyPart> sortSet;//filling sortset for interleaving parts
+    for ( std::map<int,DTSC::Track>::iterator subIt = metaData.tracks.begin(); subIt != metaData.tracks.end(); subIt ++) {
+      keyPart temp;
+      temp.trackID = subIt->second.trackID;
+      temp.time = subIt->second.firstms;//timeplace of frame
+      temp.endTime = subIt->second.firstms + subIt->second.parts[0].getDuration();
+      temp.size = subIt->second.parts[0].getSize();//bytesize of frame (alle parts all together)
+      temp.index = 0;
+      sortSet.insert(temp);
+    }
+    while (!sortSet.empty()){
+      //setting the right STCO size in the STCO box
+      checkStcoBoxes[sortSet.begin()->trackID].setChunkOffset(totalByteOffset + byteOffset, sortSet.begin()->index);
+      totalByteOffset += sortSet.begin()->size;
+      //add keyPart to sortSet
+      keyPart temp;
+      temp.index = sortSet.begin()->index + 1;
+      temp.trackID = sortSet.begin()->trackID;
+      if(temp.index < metaData.tracks[temp.trackID].parts.size() ){//only insert when there are parts left
+        temp.time = sortSet.begin()->endTime;//timeplace of frame
+        temp.endTime = sortSet.begin()->endTime + metaData.tracks[temp.trackID].parts[temp.index].getDuration();
+        temp.size = metaData.tracks[temp.trackID].parts[temp.index].getSize();//bytesize of frame 
+        sortSet.insert(temp);
+      }
+      //remove highest keyPart
+      sortSet.erase(sortSet.begin());
+    }
+    //calculating the offset where the STCO box will be in the main MOOV box
+    //needed for probable optimise
+    mdatSize = totalByteOffset;
+    
     header << std::string(moovBox.asBox(),moovBox.boxedSize());
 
     header << (char)((mdatSize>>24) & 0x000000FF) << (char)((mdatSize>>16) & 0x000000FF) << (char)((mdatSize>>8) & 0x000000FF) << (char)(mdatSize & 0x000000FF) << "mdat";
@@ -345,64 +336,5 @@ namespace MP4{
     return header.str();
   }
   
-  void DTSC2MP4Converter::parseDTSC(JSON::Value mediaPart){
-    static std::set<keyPart>::iterator curKey = keyParts.begin();//the key chunk we are currently searching for in keyParts
-    static long long unsigned int curPart = 0;//current part in current key
-    //mdat output here
-    //output cleanout buffer first
-    //while there are requested packets in the trackBuffer:...
-    while (!trackBuffer[curKey->trackID].empty()){
-      //output requested packages
-      stringBuffer += trackBuffer[curKey->trackID].front()["data"].asString();
-      trackBuffer[curKey->trackID].pop_front();
-      curPart++;
-      if(curPart >= curKey->parts.size()){
-        curPart = 0;
-        curKey++;
-      }
-    }
-    //after that, try to put out the JSON data directly
-    if(curKey->trackID == mediaPart["trackid"].asInt()){
-      //output JSON packet
-      stringBuffer += mediaPart["data"].asStringRef();
-      curPart++;
-      if(curPart >= curKey->parts.size()){
-        curPart = 0;
-        curKey++;
-      }
-    }else{
-      //buffer for later
-      trackBuffer[mediaPart["trackid"].asInt()].push_back(mediaPart);
-    }
-  }
-
-  bool DTSC2MP4Converter::sendReady(){
-    if (stringBuffer.length() > 0){
-      return true;
-    }else{
-      return false;
-    }
-  }
-  
-  std::string DTSC2MP4Converter::sendString(){
-    std::string temp = stringBuffer;
-    stringBuffer = "";
-    return temp;
-  }
-
-  std::string DTSC2MP4Converter::purgeBuffer(){
-    std::string retval = stringBuffer;
-    stringBuffer = "";
-    for (std::map <long long unsigned int, std::deque<JSON::Value> >::iterator it = trackBuffer.begin(); it !=trackBuffer.end(); it++){
-      while (!it->second.empty()){
-        //output requested packages
-        if (it->second.front()["data"].asString() != ""){
-          retval += it->second.front()["data"].asString();
-        }
-        it->second.pop_front();
-      }
-    }
-    return retval;
-  }
 }
 
diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp
new file mode 100644
index 00000000..61373ac1
--- /dev/null
+++ b/lib/mp4_generic.cpp
@@ -0,0 +1,2878 @@
+#include "mp4_generic.h"
+#include "defines.h"
+
+namespace MP4{
+  MFHD::MFHD(){
+    memcpy(data + 4, "mfhd", 4);
+    setInt32(0, 0);
+  }
+
+  void MFHD::setSequenceNumber(uint32_t newSequenceNumber){
+    setInt32(newSequenceNumber, 4);
+  }
+
+  uint32_t MFHD::getSequenceNumber(){
+    return getInt32(4);
+  }
+
+  std::string MFHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[mfhd] Movie Fragment Header (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "SequenceNumber " << getSequenceNumber() << std::endl;
+    return r.str();
+  }
+
+  MOOF::MOOF(){
+    memcpy(data + 4, "moof", 4);
+  }
+
+  TRAF::TRAF(){
+    memcpy(data + 4, "traf", 4);
+  }
+
+  uint32_t TRAF::getContentCount(){
+    int res = 0;
+    unsigned int tempLoc = 0;
+    while (tempLoc < boxedSize() - 8){
+      res++;
+      tempLoc += getBoxLen(tempLoc);
+    }
+    return res;
+  }
+
+  void TRAF::setContent(Box & newContent, uint32_t no){
+    int tempLoc = 0;
+    unsigned int contentCount = getContentCount();
+    for (unsigned int i = 0; i < no; i++){
+      if (i < contentCount){
+        tempLoc += getBoxLen(tempLoc);
+      }else{
+        if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){
+          return;
+        };
+        memset(data + tempLoc, 0, (no - contentCount) * 8);
+        tempLoc += (no - contentCount) * 8;
+        break;
+      }
+    }
+    setBox(newContent, tempLoc);
+  }
+
+  Box & TRAF::getContent(uint32_t no){
+    static Box ret = Box((char*)"\000\000\000\010erro", false);
+    if (no > getContentCount()){
+      return ret;
+    }
+    unsigned int i = 0;
+    int tempLoc = 0;
+    while (i < no){
+      tempLoc += getBoxLen(tempLoc);
+      i++;
+    }
+    return getBox(tempLoc);
+  }
+
+  std::string TRAF::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[traf] Track Fragment Box (" << boxedSize() << ")" << std::endl;
+    int contentCount = getContentCount();
+    for (int i = 0; i < contentCount; i++){
+      Box curBox = Box(getContent(i).asBox(),false);
+      r << curBox.toPrettyString(indent + 1);
+    }
+    return r.str();
+  }
+
+  TRUN::TRUN(){
+    memcpy(data + 4, "trun", 4);
+  }
+
+  void TRUN::setFlags(uint32_t newFlags){
+    setInt24(newFlags, 1);
+  }
+
+  uint32_t TRUN::getFlags(){
+    return getInt24(1);
+  }
+
+  void TRUN::setDataOffset(uint32_t newOffset){
+    if (getFlags() & trundataOffset){
+      setInt32(newOffset, 8);
+    }
+  }
+
+  uint32_t TRUN::getDataOffset(){
+    if (getFlags() & trundataOffset){
+      return getInt32(8);
+    }else{
+      return 0;
+    }
+  }
+
+  void TRUN::setFirstSampleFlags(uint32_t newSampleFlags){
+    if ( !(getFlags() & trunfirstSampleFlags)){
+      return;
+    }
+    if (getFlags() & trundataOffset){
+      setInt32(newSampleFlags, 12);
+    }else{
+      setInt32(newSampleFlags, 8);
+    }
+  }
+
+  uint32_t TRUN::getFirstSampleFlags(){
+    if ( !(getFlags() & trunfirstSampleFlags)){
+      return 0;
+    }
+    if (getFlags() & trundataOffset){
+      return getInt32(12);
+    }else{
+      return getInt32(8);
+    }
+  }
+
+  uint32_t TRUN::getSampleInformationCount(){
+    return getInt32(4);
+  }
+
+  void TRUN::setSampleInformation(trunSampleInformation newSample, uint32_t no){
+    uint32_t flags = getFlags();
+    uint32_t sampInfoSize = 0;
+    if (flags & trunsampleDuration){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleSize){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleFlags){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleOffsets){
+      sampInfoSize += 4;
+    }
+    uint32_t offset = 8;
+    if (flags & trundataOffset){
+      offset += 4;
+    }
+    if (flags & trunfirstSampleFlags){
+      offset += 4;
+    }
+    uint32_t innerOffset = 0;
+    if (flags & trunsampleDuration){
+      setInt32(newSample.sampleDuration, offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleSize){
+      setInt32(newSample.sampleSize, offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleFlags){
+      setInt32(newSample.sampleFlags, offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleOffsets){
+      setInt32(newSample.sampleOffset, offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (getSampleInformationCount() < no + 1){
+      setInt32(no + 1, 4);
+    }
+  }
+
+  trunSampleInformation TRUN::getSampleInformation(uint32_t no){
+    trunSampleInformation ret;
+    ret.sampleDuration = 0;
+    ret.sampleSize = 0;
+    ret.sampleFlags = 0;
+    ret.sampleOffset = 0;
+    if (getSampleInformationCount() < no + 1){
+      return ret;
+    }
+    uint32_t flags = getFlags();
+    uint32_t sampInfoSize = 0;
+    if (flags & trunsampleDuration){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleSize){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleFlags){
+      sampInfoSize += 4;
+    }
+    if (flags & trunsampleOffsets){
+      sampInfoSize += 4;
+    }
+    uint32_t offset = 8;
+    if (flags & trundataOffset){
+      offset += 4;
+    }
+    if (flags & trunfirstSampleFlags){
+      offset += 4;
+    }
+    uint32_t innerOffset = 0;
+    if (flags & trunsampleDuration){
+      ret.sampleDuration = getInt32(offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleSize){
+      ret.sampleSize = getInt32(offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleFlags){
+      ret.sampleFlags = getInt32(offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    if (flags & trunsampleOffsets){
+      ret.sampleOffset = getInt32(offset + no * sampInfoSize + innerOffset);
+      innerOffset += 4;
+    }
+    return ret;
+  }
+
+  std::string TRUN::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[trun] Track Fragment Run (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl;
+
+    uint32_t flags = getFlags();
+    r << std::string(indent + 1, ' ') << "Flags";
+    if (flags & trundataOffset){
+      r << " dataOffset";
+    }
+    if (flags & trunfirstSampleFlags){
+      r << " firstSampleFlags";
+    }
+    if (flags & trunsampleDuration){
+      r << " sampleDuration";
+    }
+    if (flags & trunsampleSize){
+      r << " sampleSize";
+    }
+    if (flags & trunsampleFlags){
+      r << " sampleFlags";
+    }
+    if (flags & trunsampleOffsets){
+      r << " sampleOffsets";
+    }
+    r << std::endl;
+
+    if (flags & trundataOffset){
+      r << std::string(indent + 1, ' ') << "Data Offset " << getDataOffset() << std::endl;
+    }
+    if (flags & trundataOffset){
+      r << std::string(indent + 1, ' ') << "Sample Flags" << prettySampleFlags(getFirstSampleFlags()) << std::endl;
+    }
+
+    r << std::string(indent + 1, ' ') << "SampleInformation (" << getSampleInformationCount() << "):" << std::endl;
+    for (unsigned int i = 0; i < getSampleInformationCount(); ++i){
+      r << std::string(indent + 2, ' ') << "[" << i << "] ";
+      trunSampleInformation samp = getSampleInformation(i);
+      if (flags & trunsampleDuration){
+        r << "Duration=" << samp.sampleDuration << " ";
+      }
+      if (flags & trunsampleSize){
+        r << "Size=" << samp.sampleSize << " ";
+      }
+      if (flags & trunsampleFlags){
+        r << "Flags=" << prettySampleFlags(samp.sampleFlags) << " ";
+      }
+      if (flags & trunsampleOffsets){
+        r << "Offset=" << samp.sampleOffset << " ";
+      }
+      r << std::endl;
+    }
+
+    return r.str();
+  }
+
+  std::string prettySampleFlags(uint32_t flag){
+    std::stringstream r;
+    if (flag & noIPicture){
+      r << " noIPicture";
+    }
+    if (flag & isIPicture){
+      r << " isIPicture";
+    }
+    if (flag & noDisposable){
+      r << " noDisposable";
+    }
+    if (flag & isDisposable){
+      r << " isDisposable";
+    }
+    if (flag & isRedundant){
+      r << " isRedundant";
+    }
+    if (flag & noRedundant){
+      r << " noRedundant";
+    }
+    if (flag & noKeySample){
+      r << " noKeySample";
+    }else{
+      r << " isKeySample";
+    }
+    return r.str();
+  }
+
+  TFHD::TFHD(){
+    memcpy(data + 4, "tfhd", 4);
+  }
+
+  void TFHD::setFlags(uint32_t newFlags){
+    setInt24(newFlags, 1);
+  }
+
+  uint32_t TFHD::getFlags(){
+    return getInt24(1);
+  }
+
+  void TFHD::setTrackID(uint32_t newID){
+    setInt32(newID, 4);
+  }
+
+  uint32_t TFHD::getTrackID(){
+    return getInt32(4);
+  }
+
+  void TFHD::setBaseDataOffset(uint64_t newOffset){
+    if (getFlags() & tfhdBaseOffset){
+      setInt64(newOffset, 8);
+    }
+  }
+
+  uint64_t TFHD::getBaseDataOffset(){
+    if (getFlags() & tfhdBaseOffset){
+      return getInt64(8);
+    }else{
+      return 0;
+    }
+  }
+
+  void TFHD::setSampleDescriptionIndex(uint32_t newIndex){
+    if ( !(getFlags() & tfhdSampleDesc)){
+      return;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    setInt32(newIndex, offset);
+  }
+
+  uint32_t TFHD::getSampleDescriptionIndex(){
+    if ( !(getFlags() & tfhdSampleDesc)){
+      return 0;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    return getInt32(offset);
+  }
+
+  void TFHD::setDefaultSampleDuration(uint32_t newDuration){
+    if ( !(getFlags() & tfhdSampleDura)){
+      return;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    setInt32(newDuration, offset);
+  }
+
+  uint32_t TFHD::getDefaultSampleDuration(){
+    if ( !(getFlags() & tfhdSampleDura)){
+      return 0;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    return getInt32(offset);
+  }
+
+  void TFHD::setDefaultSampleSize(uint32_t newSize){
+    if ( !(getFlags() & tfhdSampleSize)){
+      return;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleDura){
+      offset += 4;
+    }
+    setInt32(newSize, offset);
+  }
+
+  uint32_t TFHD::getDefaultSampleSize(){
+    if ( !(getFlags() & tfhdSampleSize)){
+      return 0;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleDura){
+      offset += 4;
+    }
+    return getInt32(offset);
+  }
+
+  void TFHD::setDefaultSampleFlags(uint32_t newFlags){
+    if ( !(getFlags() & tfhdSampleFlag)){
+      return;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleDura){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleSize){
+      offset += 4;
+    }
+    setInt32(newFlags, offset);
+  }
+
+  uint32_t TFHD::getDefaultSampleFlags(){
+    if ( !(getFlags() & tfhdSampleFlag)){
+      return 0;
+    }
+    int offset = 8;
+    if (getFlags() & tfhdBaseOffset){
+      offset += 8;
+    }
+    if (getFlags() & tfhdSampleDesc){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleDura){
+      offset += 4;
+    }
+    if (getFlags() & tfhdSampleSize){
+      offset += 4;
+    }
+    return getInt32(offset);
+  }
+
+  std::string TFHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[tfhd] Track Fragment Header (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version " << (int)getInt8(0) << std::endl;
+
+    uint32_t flags = getFlags();
+    r << std::string(indent + 1, ' ') << "Flags";
+    if (flags & tfhdBaseOffset){
+      r << " BaseOffset";
+    }
+    if (flags & tfhdSampleDesc){
+      r << " SampleDesc";
+    }
+    if (flags & tfhdSampleDura){
+      r << " SampleDura";
+    }
+    if (flags & tfhdSampleSize){
+      r << " SampleSize";
+    }
+    if (flags & tfhdSampleFlag){
+      r << " SampleFlag";
+    }
+    if (flags & tfhdNoDuration){
+      r << " NoDuration";
+    }
+    r << std::endl;
+
+    r << std::string(indent + 1, ' ') << "TrackID " << getTrackID() << std::endl;
+
+    if (flags & tfhdBaseOffset){
+      r << std::string(indent + 1, ' ') << "Base Offset " << getBaseDataOffset() << std::endl;
+    }
+    if (flags & tfhdSampleDesc){
+      r << std::string(indent + 1, ' ') << "Sample Description Index " << getSampleDescriptionIndex() << std::endl;
+    }
+    if (flags & tfhdSampleDura){
+      r << std::string(indent + 1, ' ') << "Default Sample Duration " << getDefaultSampleDuration() << std::endl;
+    }
+    if (flags & tfhdSampleSize){
+      r << std::string(indent + 1, ' ') << "Default Same Size " << getDefaultSampleSize() << std::endl;
+    }
+    if (flags & tfhdSampleFlag){
+      r << std::string(indent + 1, ' ') << "Default Sample Flags " << prettySampleFlags(getDefaultSampleFlags()) << std::endl;
+    }
+
+    return r.str();
+  }
+
+
+  AVCC::AVCC(){
+    memcpy(data + 4, "avcC", 4);
+    setInt8(0xFF, 4); //reserved + 4-bytes NAL length
+  }
+
+  void AVCC::setVersion(uint32_t newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  uint32_t AVCC::getVersion(){
+    return getInt8(0);
+  }
+
+  void AVCC::setProfile(uint32_t newProfile){
+    setInt8(newProfile, 1);
+  }
+
+  uint32_t AVCC::getProfile(){
+    return getInt8(1);
+  }
+
+  void AVCC::setCompatibleProfiles(uint32_t newCompatibleProfiles){
+    setInt8(newCompatibleProfiles, 2);
+  }
+
+  uint32_t AVCC::getCompatibleProfiles(){
+    return getInt8(2);
+  }
+
+  void AVCC::setLevel(uint32_t newLevel){
+    setInt8(newLevel, 3);
+  }
+
+  uint32_t AVCC::getLevel(){
+    return getInt8(3);
+  }
+
+  void AVCC::setSPSNumber(uint32_t newSPSNumber){
+    setInt8(newSPSNumber, 5);
+  }
+
+  uint32_t AVCC::getSPSNumber(){
+    return getInt8(5);
+  }
+
+  void AVCC::setSPS(std::string newSPS){
+    setInt16(newSPS.size(), 6);
+    for (unsigned int i = 0; i < newSPS.size(); i++){
+      setInt8(newSPS[i], 8 + i);
+    } //not null-terminated
+  }
+
+  uint32_t AVCC::getSPSLen(){
+    return getInt16(6);
+  }
+
+  char* AVCC::getSPS(){
+    return payload() + 8;
+  }
+
+  void AVCC::setPPSNumber(uint32_t newPPSNumber){
+    int offset = 8 + getSPSLen();
+    setInt8(newPPSNumber, offset);
+  }
+
+  uint32_t AVCC::getPPSNumber(){
+    int offset = 8 + getSPSLen();
+    return getInt8(offset);
+  }
+
+  void AVCC::setPPS(std::string newPPS){
+    int offset = 8 + getSPSLen() + 1;
+    setInt16(newPPS.size(), offset);
+    for (unsigned int i = 0; i < newPPS.size(); i++){
+      setInt8(newPPS[i], offset + 2 + i);
+    } //not null-terminated
+  }
+
+  uint32_t AVCC::getPPSLen(){
+    int offset = 8 + getSPSLen() + 1;
+    return getInt16(offset);
+  }
+
+  char* AVCC::getPPS(){
+    int offset = 8 + getSPSLen() + 3;
+    return payload() + offset;
+  }
+
+  std::string AVCC::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[avcC] H.264 Init Data (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "Profile: " << getProfile() << std::endl;
+    r << std::string(indent + 1, ' ') << "Compatible Profiles: " << getCompatibleProfiles() << std::endl;
+    r << std::string(indent + 1, ' ') << "Level: " << getLevel() << std::endl;
+    r << std::string(indent + 1, ' ') << "SPS Number: " << getSPSNumber() << std::endl;
+    r << std::string(indent + 2, ' ') << getSPSLen() << " of SPS data" << std::endl;
+    r << std::string(indent + 1, ' ') << "PPS Number: " << getPPSNumber() << std::endl;
+    r << std::string(indent + 2, ' ') << getPPSLen() << " of PPS data" << std::endl;
+    return r.str();
+  }
+
+  std::string AVCC::asAnnexB(){
+    std::stringstream r;
+    r << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01;
+    r.write(getSPS(), getSPSLen());
+    r << (char)0x00 << (char)0x00 << (char)0x00 << (char)0x01;
+    r.write(getPPS(), getPPSLen());
+    return r.str();
+  }
+
+  void AVCC::setPayload(std::string newPayload){
+    if ( !reserve(0, payloadSize(), newPayload.size())){
+      DEBUG_MSG(DLVL_ERROR, "Cannot allocate enough memory for payload");
+      return;
+    }
+    memcpy((char*)payload(), (char*)newPayload.c_str(), newPayload.size());
+  }
+  
+  //fullbox, start at 4
+  ESDS::ESDS(){
+    memcpy(data + 4, "esds", 4);
+    setESDescriptorType(0x03);
+    setExtendedESDescriptorType(0x808080);
+    setStreamPriority(16);
+    setDecoderConfigDescriptorTag(0x04);
+    setExtendedDecoderConfigDescriptorTag(0x808080);
+    setReservedFlag(true);
+    setDecoderDescriptorTypeTag(0x05);
+    setExtendedDecoderDescriptorTypeTag(0x808080);
+    setSLConfigDescriptorTypeTag(0x06);
+    setSLConfigExtendedDescriptorTypeTag(0x808010);
+    setSLValue(0x02);
+  }
+  
+  ESDS::ESDS(std::string init, uint32_t bps){
+    memcpy(data + 4, "esds", 4);
+    char temp[] = {0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x80, 0x80, 0x00, 0x00, 0x02, 0x10, 0x04, 0x80, 0x80, 0x80, 0x00, 0x40, 0x15, 0x13, 0x12, 0xD0, 0x00, 0x98, 0x96, 0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x80, 0x80, 0x05};
+    setString(temp, 0x23,0);
+    setESDescriptorTypeLength(32 + init.size());
+    setDecoderConfigDescriptorTypeLength(18 + init.size());
+    setAverageBitRate(bps * 8);
+    setESHeaderStartCodes(init);
+    char temp2[] = {0x05, 0x80, 0x80, 0x10, 0x01, 0x02};
+    setString(temp2, 0x06, 0x23 + 32 + init.size());
+  }
+  
+  char ESDS::getESDescriptorType(){
+    return getInt8(4);
+  }
+  
+  void ESDS::setESDescriptorType(char newVal){
+    setInt8(newVal,4);
+  }
+  
+  uint32_t ESDS::getExtendedESDescriptorType(){
+    return getInt24(5);
+  }
+  //3 bytes
+  void ESDS::setExtendedESDescriptorType(uint32_t newVal){
+    setInt24(newVal,5);
+  }
+  //3 bytes
+  char ESDS::getESDescriptorTypeLength(){
+    return getInt8(8);  
+  }
+  
+  void ESDS::setESDescriptorTypeLength(char newVal){
+    setInt8(newVal,8);
+  }
+  //ESID 2 bytes
+  uint16_t ESDS::getESID(){
+    return getInt16(9);
+  }
+  
+  void ESDS::setESID(uint16_t newVal){
+    setInt16(newVal, 9);
+  }
+  
+  //stream priority 1 byte
+  char ESDS::getStreamPriority(){
+    return getInt8(11);
+  }
+  
+  void ESDS::setStreamPriority(char newVal){
+    setInt8(newVal, 11);
+  }
+  
+  //decoder config descriptor tag 1byte
+  char ESDS::getDecoderConfigDescriptorTag(){
+    return getInt8(12);
+  }
+  
+  void ESDS::setDecoderConfigDescriptorTag(char newVal){
+    setInt8(newVal, 12);
+  }
+  
+  //extended decoder config descriptor tag 3 bytes
+  uint32_t ESDS::getExtendedDecoderConfigDescriptorTag(){
+    return getInt24(13);
+  }
+  //3 bytes
+  void ESDS::setExtendedDecoderConfigDescriptorTag(uint32_t newVal){
+    setInt24(newVal, 13);
+  }
+  //3 bytes
+  //decoder config descriptor type length
+  char ESDS::getDecoderConfigDescriptorTypeLength(){
+    return getInt8(16);
+  }
+  
+  void ESDS::setDecoderConfigDescriptorTypeLength(char newVal){
+    setInt8(newVal, 16);
+  }
+  //Note: count 8 bytes extra in the next four functions
+  char ESDS::getByteObjectTypeID(){
+    return getInt8(17);  
+  }
+  
+  void ESDS::setByteObjectTypeID(char newVal){
+    setInt8(newVal,17);
+  }
+  
+  char ESDS::getStreamType(){
+    return getInt8(18) >> 2;  
+  }
+  //6 bits
+  void ESDS::setStreamType(char newVal){
+    setInt8(((newVal << 2) & 0xFC) + (getInt8(18) & 0x03), 18);
+  }
+  //6 bits
+  bool ESDS::getUpstreamFlag(){
+    return (((getInt8(18) >> 1) & 0x01) == 1);  
+  }
+  
+  void ESDS::setUpstreamFlag(bool newVal){
+    setInt8((getStreamType()<<2) + ((uint8_t)newVal << 1) + (uint8_t)getReservedFlag() , 18);
+  }
+  
+  bool ESDS::getReservedFlag(){
+    return ((getInt8(18) & 0x01) == 1);  
+  }
+  
+  void ESDS::setReservedFlag(bool newVal){
+    setInt8((getInt8(18) & 0xFE) + (int)newVal, 18);
+  }
+  
+  uint32_t ESDS::getBufferSize(){
+    return getInt24(19);  
+  }
+  //3 bytes
+  void ESDS::setBufferSize(uint32_t newVal){
+    setInt24(newVal,19);
+  }
+  //3 bytes
+  uint32_t ESDS::getMaximumBitRate(){
+    return getInt32(22);  
+  }
+  
+  void ESDS::setMaximumBitRate(uint32_t newVal){
+    setInt32(newVal,22);
+  }
+  
+  uint32_t ESDS::getAverageBitRate(){
+    return getInt32(26);  
+  }
+  
+  void ESDS::setAverageBitRate(uint32_t newVal){
+    setInt32(newVal,26);
+  }
+  
+  char ESDS::getDecoderDescriptorTypeTag(){
+    return getInt8(30);
+  }
+  
+  void ESDS::setDecoderDescriptorTypeTag(char newVal){
+    setInt8(newVal,30);
+  }
+  
+  uint32_t ESDS::getExtendedDecoderDescriptorTypeTag(){
+    return getInt24(31);
+  }
+  
+  //3 bytes
+  void ESDS::setExtendedDecoderDescriptorTypeTag(uint32_t newVal){
+    setInt24(newVal, 31);
+  }
+
+  //3 bytes
+  char ESDS::getConfigDescriptorTypeLength(){
+    return getInt8(34);
+  }
+  
+  void ESDS::setConfigDescriptorTypeLength(char newVal){
+    setInt8(newVal, 34);
+  }
+  
+  std::string ESDS::getESHeaderStartCodes(){
+    std::string result;
+    for (int i = 0; i < getInt8(34); i++){
+      result += getInt8(35 + i);
+    }
+    return result;
+  }
+  
+  void ESDS::setESHeaderStartCodes(std::string newVal){
+    setConfigDescriptorTypeLength(newVal.size());
+    for (unsigned int i = 0; i < newVal.size(); i++){
+      setInt8(newVal[i],35+i);
+    }
+  }
+  
+  char ESDS::getSLConfigDescriptorTypeTag(){
+    return getInt8(35 + getInt8(34));  
+  }
+  
+  void ESDS::setSLConfigDescriptorTypeTag(char newVal){
+    setInt8(newVal, 35 + getInt8(34));
+  }
+  
+  uint32_t ESDS::getSLConfigExtendedDescriptorTypeTag(){
+    return getInt24(36 + getInt8(34));  
+  }
+  //3 bytes
+  void ESDS::setSLConfigExtendedDescriptorTypeTag(uint32_t newVal){
+    setInt24(newVal, 36 + getInt8(34));
+  }
+  //3 bytes
+  char ESDS::getSLDescriptorTypeLength(){
+    return getInt8(39 + getInt8(34));
+  }
+  
+  void ESDS::setSLDescriptorTypeLength(char newVal){
+    setInt8(newVal, 39 + getInt8(34));
+  }
+  
+  char ESDS::getSLValue(){
+    return getInt8(40 + getInt8(34));
+  }
+  
+  void ESDS::setSLValue(char newVal){
+    setInt8(newVal, 40 + getInt8(34));
+  }
+  
+  std::string ESDS::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[esds] ES Descriptor Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "ESDescriptorType: 0x" << std::hex << (int)getESDescriptorType() << std::dec << std::endl;    
+    r << std::string(indent + 1, ' ') << "ExtendedESDescriptorType: 0x" << std::hex << (int)getExtendedESDescriptorType() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "ESDescriptorTypeLength:"  << (int)getESDescriptorTypeLength() << std::endl;
+    r << std::string(indent + 1, ' ') << "ESID: 0x" << std::hex << (int)getESID() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "StreamPriority: 0x" << std::hex << (int)getStreamPriority() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "DecoderConfigDescriptorTag: 0x" << std::hex << (int)getDecoderConfigDescriptorTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "ExtendedDecoderConfigDescriptorTag: 0x" << std::hex << (int)getExtendedDecoderConfigDescriptorTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "DecoderConfigDescriptorTypeLength: " << (int)getDecoderConfigDescriptorTypeLength() << std::endl;
+    r << std::string(indent + 1, ' ') << "ByteObjectTypeID: 0x" << std::hex << (int)getByteObjectTypeID() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "StreamType: 0x" << std::hex << (int)getStreamType() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "UpstreamFlag: 0x" << std::hex << (int)getUpstreamFlag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "BufferSize: 0x" << std::hex << (int)getBufferSize() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "MaximumBitRate: 0x" << std::hex << (int)getMaximumBitRate() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "AverageBitRate: 0x" << std::hex << (int)getAverageBitRate() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "DecoderDescriptorTypeTag: 0x" << std::hex << (int)getDecoderDescriptorTypeTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "ExtendedDecoderDescriptorTypeTag: 0x" << std::hex << (int)getExtendedDecoderDescriptorTypeTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "ConfigDescriptorTypeLength: 0x" << std::hex << (int)getConfigDescriptorTypeLength() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "ESHeaderStartCodes: 0x";
+    for (unsigned int i = 0; i<getESHeaderStartCodes().size(); i++){
+      r << std::hex << std::setw(2) << std::setfill('0') << (int)getESHeaderStartCodes()[i] << std::dec;
+    }
+    r << std::endl;
+    r << std::string(indent + 1, ' ') << "SLConfigDescriptorTypeTag: 0x" << std::hex << (int)getSLConfigDescriptorTypeTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "SLConfigExtendedDescriptorTypeTag: 0x" << std::hex << (int)getSLConfigExtendedDescriptorTypeTag() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "SLDescriptorTypeLength: 0x" << std::hex << (int)getSLDescriptorTypeLength() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "SLValue: 0x" << std::hex << (int)getSLValue() << std::dec << std::endl;
+    return r.str();
+  }
+  
+  FTYP::FTYP(){
+    memcpy(data + 4, "ftyp", 4);
+    setMajorBrand(0);
+    setMinorVersion(0);
+  }
+  
+  void FTYP::setMajorBrand(uint32_t newMajorBrand){
+    setInt32(newMajorBrand, 0);
+  }
+  
+  uint32_t FTYP::getMajorBrand(){
+    return getInt32(0);
+  }
+  
+  void FTYP::setMinorVersion(uint32_t newMinorVersion){
+    setInt32(newMinorVersion, 4);
+  }
+  
+  uint32_t FTYP::getMinorVersion(){
+    return getInt32(4);
+  }
+  
+  uint32_t FTYP::getCompatibleBrandsCount(){
+    return (payloadSize() - 8) / 4;
+  }
+  
+  void FTYP::setCompatibleBrands(uint32_t newCompatibleBrand, size_t index){
+    setInt32(newCompatibleBrand, 8 + (index * 4));
+  }
+  
+  uint32_t FTYP::getCompatibleBrands(size_t index){
+    if (index >= getCompatibleBrandsCount()){
+      return 0;
+    }
+    return getInt32(8 + (index * 4));
+  }
+  
+  std::string FTYP::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[ftyp] File Type (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "MajorBrand: 0x" << std::hex << getMajorBrand() << std::dec << std::endl;
+    r << std::string(indent + 1, ' ') << "MinorVersion: " << getMinorVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl;
+    for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++){
+      r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: 0x" << std::hex << getCompatibleBrands(i) << std::dec << std::endl;
+    }
+    return r.str();
+  }
+  
+  MOOV::MOOV(){
+    memcpy(data + 4, "moov", 4);
+  }
+  
+  MVEX::MVEX(){
+    memcpy(data + 4, "mvex", 4);
+  }
+  
+  TREX::TREX(){
+    memcpy(data + 4, "trex", 4);
+  }
+  
+  void TREX::setTrackID(uint32_t newTrackID){
+    setInt32(newTrackID, 0);
+  }
+  
+  uint32_t TREX::getTrackID(){
+    return getInt32(0);
+  }
+  
+  void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex){
+    setInt32(newDefaultSampleDescriptionIndex,4);
+  }
+  
+  uint32_t TREX::getDefaultSampleDescriptionIndex(){
+    return getInt32(4);
+  }
+  
+  void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration){
+    setInt32(newDefaultSampleDuration,8);
+  }
+  
+  uint32_t TREX::getDefaultSampleDuration(){
+    return getInt32(8);
+  }
+  
+  void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize){
+    setInt32(newDefaultSampleSize,12);
+  }
+  
+  uint32_t TREX::getDefaultSampleSize(){
+    return getInt32(12);
+  }
+  
+  void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags){
+    setInt32(newDefaultSampleFlags,16);
+  }
+  
+  uint32_t TREX::getDefaultSampleFlags(){
+    return getInt32(16);
+  }
+  
+  std::string TREX::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[trex] Track Extends (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
+    r << std::string(indent + 1, ' ') << "DefaultSampleDescriptionIndex : " << getDefaultSampleDescriptionIndex() << std::endl;
+    r << std::string(indent + 1, ' ') << "DefaultSampleDuration : " << getDefaultSampleDuration() << std::endl;
+    r << std::string(indent + 1, ' ') << "DefaultSampleSize : " << getDefaultSampleSize() << std::endl;
+    r << std::string(indent + 1, ' ') << "DefaultSampleFlags : " << getDefaultSampleFlags() << std::endl;
+    return r.str();
+  }
+
+  TRAK::TRAK(){
+    memcpy(data + 4, "trak", 4);
+  }
+  
+  MDIA::MDIA(){
+    memcpy(data + 4, "mdia", 4);
+  }
+  
+  MINF::MINF(){
+    memcpy(data + 4, "minf", 4);
+  }
+  
+  DINF::DINF(){
+    memcpy(data + 4, "dinf", 4);
+  }
+  
+  MFRA::MFRA(){
+    memcpy(data + 4, "mfra", 4);
+  }
+  
+  MFRO::MFRO(){
+    memcpy(data + 4, "mfro", 4);
+  }
+
+  void MFRO::setSize(uint32_t newSize){
+    setInt32(newSize,0);
+  }
+  
+  uint32_t MFRO::getSize(){
+    return getInt32(0);
+  }
+  
+  std::string MFRO::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[mfro] Movie Fragment Random Access Offset (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Size: " << getSize() << std::endl;
+    return r.str();
+  }
+  
+  HDLR::HDLR(){
+    memcpy(data + 4, "hdlr", 4);
+    setName("");
+  }
+  
+  void HDLR::setSize(uint32_t newSize){
+    setInt32(newSize,0);
+  }
+  
+  uint32_t HDLR::getSize(){
+    return getInt32(0);
+  }
+  
+  void HDLR::setPreDefined(uint32_t newPreDefined){
+    setInt32(newPreDefined,4);
+  }
+  
+  uint32_t HDLR::getPreDefined(){
+    return getInt32(4);
+  }
+  
+  void HDLR::setHandlerType(uint32_t newHandlerType){
+    setInt32(newHandlerType, 8);
+  }
+  
+  uint32_t HDLR::getHandlerType(){
+    return getInt32(8);
+  }
+  
+  void HDLR::setName(std::string newName){
+    setString(newName, 24);
+  }
+  
+  std::string HDLR::getName(){
+    return getString(24);
+  }
+  
+  std::string HDLR::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[hdlr] Handler Reference (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl;
+    r << std::string(indent + 1, ' ') << "HandlerType: " << 
+      (char)((getHandlerType() & 0xFF000000) >> 24) << (char)((getHandlerType() & 0x00FF0000) >> 16) <<
+      (char)((getHandlerType() & 0x0000FF00) >> 8) << (char)(getHandlerType() & 0x000000FF) << std::endl;
+    r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl;
+    return r.str();
+  }
+  
+  //Note: next 4 headers inherit from fullBox, start at byte 4.
+  VMHD::VMHD(){
+    memcpy(data + 4, "vmhd", 4);
+    setGraphicsMode(0);
+    setOpColor(0,0);
+    setOpColor(0,1);
+    setOpColor(0,2);
+  }
+  
+  void VMHD::setGraphicsMode(uint16_t newGraphicsMode){
+    setInt16(newGraphicsMode,4);
+  }
+  
+  uint16_t VMHD::getGraphicsMode(){
+    return getInt16(4);
+  }
+  
+  uint32_t VMHD::getOpColorCount(){
+    return 3;
+  }
+  
+  void VMHD::setOpColor(uint16_t newOpColor, size_t index){
+    if (index <3){
+      setInt16(newOpColor, 6 + (2 * index));
+    }
+  }
+  
+  uint16_t VMHD::getOpColor(size_t index){
+    if (index < 3){
+      return getInt16(6 + (index * 2));
+    }else{
+      return 0;
+    }
+  }
+  
+  std::string VMHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[vmhd] Video Media Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "GraphicsMode: " << getGraphicsMode() << std::endl;
+    for (unsigned int i = 0; i < getOpColorCount(); i++){
+      r << std::string(indent + 1, ' ') << "OpColor["<<i<<"]: " << getOpColor(i) << std::endl;
+    }
+    return r.str();
+  }
+    
+  SMHD::SMHD(){
+    memcpy(data + 4, "smhd", 4);
+    setBalance(0);
+    setInt16(0,6);
+  }
+  
+  void SMHD::setBalance(int16_t newBalance){
+    setInt16(newBalance,4);
+  }
+  
+  int16_t SMHD::getBalance(){
+    return getInt16(4);
+  }
+  
+  std::string SMHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[smhd] Sound Media Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "Balance: " << getBalance() << std::endl;
+    return r.str();
+  }
+
+  HMHD::HMHD(){
+    memcpy(data + 4, "hmhd", 4);
+  }
+  
+  void HMHD::setMaxPDUSize(uint16_t newMaxPDUSize){
+    setInt16(newMaxPDUSize,4);
+  }
+  
+  uint16_t HMHD::getMaxPDUSize(){
+    return getInt16(4);
+  }
+  
+  void HMHD::setAvgPDUSize(uint16_t newAvgPDUSize){
+    setInt16(newAvgPDUSize,6);
+  }
+  
+  uint16_t HMHD::getAvgPDUSize(){
+    return getInt16(6);
+  }
+  
+  void HMHD::setMaxBitRate(uint32_t newMaxBitRate){
+    setInt32(newMaxBitRate,8);
+  }
+  
+  uint32_t HMHD::getMaxBitRate(){
+    return getInt32(8);
+  }
+  
+  void HMHD::setAvgBitRate(uint32_t newAvgBitRate){
+    setInt32(newAvgBitRate,12);
+  }
+  
+  uint32_t HMHD::getAvgBitRate(){
+    return getInt32(12);
+  }
+  
+  std::string HMHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[hmhd] Hint Media Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "maxPDUSize: " << getMaxPDUSize() << std::endl;
+    r << std::string(indent + 1, ' ') << "avgPDUSize: " << getAvgPDUSize() << std::endl;
+    r << std::string(indent + 1, ' ') << "maxBitRate: " << getMaxBitRate() << std::endl;
+    r << std::string(indent + 1, ' ') << "avgBitRate: " << getAvgBitRate() << std::endl;
+    return r.str();
+  }
+  
+  NMHD::NMHD(){
+    memcpy(data + 4, "nmhd", 4);
+  }
+  
+  std::string NMHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[nmhd] Null Media Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    return r.str();
+  }
+  
+  MEHD::MEHD(){
+    memcpy(data + 4, "mehd", 4);
+  }
+  
+  void MEHD::setFragmentDuration(uint64_t newFragmentDuration){
+    if (getVersion() == 0){
+      setInt32(newFragmentDuration,4);
+    }else{
+      setInt64(newFragmentDuration,4);
+    }
+  }
+  
+  uint64_t MEHD::getFragmentDuration(){
+    if(getVersion() == 0){
+      return getInt32(4);
+    }else{
+      return getInt64(4);
+    }
+  }
+  
+  std::string MEHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[mehd] Movie Extends Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "FragmentDuration: " << getFragmentDuration() << std::endl;
+    return r.str();
+  }
+  
+  STBL::STBL(){
+    memcpy(data + 4, "stbl", 4);
+  }
+  
+  URL::URL(){
+    memcpy(data + 4, "url ", 4);
+  }
+  
+  void URL::setLocation(std::string newLocation){
+    setString(newLocation, 4);
+  }
+  
+  std::string URL::getLocation(){
+    return std::string(getString(4),getStringLen(4));
+  }
+  
+  std::string URL::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[url ] URL Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "Location: " << getLocation() << std::endl;
+    return r.str();
+  }
+
+  URN::URN(){
+    memcpy(data + 4, "urn ", 4);
+  }
+  
+  void URN::setName(std::string newName){
+    setString(newName, 4);
+  }
+  
+  std::string URN::getName(){
+    return std::string(getString(4),getStringLen(4));
+  }
+  
+  void URN::setLocation(std::string newLocation){
+    setString(newLocation, 4 + getStringLen(4) + 1);
+  }
+  
+  std::string URN::getLocation(){
+    int loc = 4 + getStringLen(4) + 1;
+    return std::string(getString(loc),getStringLen(loc));
+  }
+  
+  std::string URN::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[urn ] URN Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl;
+    r << std::string(indent + 1, ' ') << "Location: " << getLocation() << std::endl;
+    return r.str();
+  }
+
+  DREF::DREF(char v, uint32_t f){
+    memcpy(data + 4, "dref", 4);
+    setVersion(v);
+    setFlags(f);
+    setInt32(0,4);
+  }
+  
+  uint32_t DREF::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void DREF::setDataEntry(fullBox & newDataEntry, size_t index){
+    unsigned int i;
+    uint32_t offset = 8; //start of boxes
+    for (i=0; i< getEntryCount() && i < index; i++){
+      offset += getBoxLen(offset);
+    }
+    if (index+1 > getEntryCount()){
+      int amount = index + 1 - getEntryCount();
+      if ( !reserve(payloadOffset + offset, 0, amount * 8)){
+        return;
+      }
+      for (int j = 0; j < amount; ++j){
+        memcpy(data + payloadOffset + offset + j * 8, "\000\000\000\010erro", 8);
+      }
+      setInt32(index + 1, 4);
+      offset += (index - i) * 8;
+    }
+    setBox(newDataEntry, offset);
+  }
+  
+  Box & DREF::getDataEntry(size_t index){
+    uint32_t offset = 8;
+    if (index > getEntryCount()){
+      static Box res;
+      return (Box &)res;
+    }
+    
+    for (unsigned int i=0; i < index; i++){
+      offset += getBoxLen(offset);
+    }
+    return (Box &)getBox(offset);
+  }
+  
+  std::string DREF::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[dref] Data Reference Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i< getEntryCount(); i++){
+      r << getDataEntry(i).toPrettyString(indent+1);
+    }
+    return r.str();
+  }
+  
+  MVHD::MVHD(char v, uint32_t f){
+    memcpy(data + 4, "mvhd", 4);
+    setVersion(v);
+    setFlags(f);
+    setCreationTime(0);
+    setModificationTime(0);
+    setTimeScale(1000);
+    setDuration(0);
+    setRate(0x00010000);
+    setVolume(0x0100);
+    setMatrix(0x40000000,0);
+    setMatrix(0x00010000,4);
+    setMatrix(0x00010000,8);
+    setTrackID(1);
+  }
+  
+  MVHD::MVHD(long long unsigned int duration){
+    //memcpy(data + 4, "mvhd", 4);
+    //char temp[] =  {00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x03, 0xE8, 0x10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00};
+    //char temp[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x3d, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+    //setString(temp, 0x4F, 0);
+    //setDuration(duration);
+    
+    memcpy(data + 4, "mvhd", 4);
+    setVersion(0);
+    setFlags(0);
+    setTrackID(1);
+    setTimeScale(1000);
+
+    setRate(0x00010000);
+    setVolume(0x0100);
+    setMatrix(0x40000000,0);
+    setMatrix(0x00010000,4);
+    setMatrix(0x00010000,8);
+    setTimeScale(1000);
+    setRate(0x10000);
+    
+    setDuration(duration);
+  }
+  
+  void MVHD::setCreationTime(uint64_t newCreationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newCreationTime, 4);
+    }else{
+      setInt64(newCreationTime, 4);
+    }
+  }
+  
+  uint64_t MVHD::getCreationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(4);
+    }else{
+      return getInt64(4);
+    }
+  }
+  
+  void MVHD::setModificationTime(uint64_t newModificationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newModificationTime, 8);
+    }else{
+      setInt64(newModificationTime, 12);
+    }
+  }
+  
+  uint64_t MVHD::getModificationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(8);
+    }else{
+      return getInt64(12);
+    }
+  }
+  
+  void MVHD::setTimeScale(uint32_t newTimeScale){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newTimeScale, 12);
+    }else{
+      setInt32(newTimeScale, 20);
+    }
+  }
+  
+  uint32_t MVHD::getTimeScale(){
+    if (getVersion() == 0){
+      return getInt32(12);
+    }else{
+      return getInt32(20);
+    }
+  }
+  
+  void MVHD::setDuration(uint64_t newDuration){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newDuration, 16);
+    }else{
+      setInt64(newDuration, 24);
+    }
+  }
+  
+  uint64_t MVHD::getDuration(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(16);
+    }else{
+      return getInt64(24);
+    }
+  }
+  
+  void MVHD::setRate(uint32_t newRate){
+    if (getVersion() == 0){
+      setInt32( newRate, 20);
+    }else{
+      setInt32(newRate, 32);
+    }
+  }
+  
+  uint32_t MVHD::getRate(){
+    if (getVersion() == 0){
+      return getInt32(20);
+    }else{
+      return getInt32(32);
+    }
+  }
+  
+  void MVHD::setVolume(uint16_t newVolume){
+    if (getVersion() == 0){
+      setInt16(newVolume, 24);
+    }else{
+      setInt16(newVolume, 36);
+    }
+  }
+  
+  uint16_t MVHD::getVolume(){
+    if (getVersion() == 0){
+      return getInt16(24);
+    }else{
+      return getInt16(36);
+    }
+  }
+  //10 bytes reserved in between
+  uint32_t MVHD::getMatrixCount(){
+    return 9;
+  }
+  
+  void MVHD::setMatrix(int32_t newMatrix, size_t index){
+    int offset = 0;
+    if (getVersion() == 0){
+      offset = 24 + 2 + 10;
+    }else{
+      offset = 36 + 2 + 10;
+    }
+    setInt32(newMatrix, offset + index * 4);
+  }
+  
+  int32_t MVHD::getMatrix(size_t index){
+    int offset = 0;
+    if (getVersion() == 0){
+      offset = 24 + 2 + 10;
+    }else{
+      offset = 36 + 2 + 10;
+    }
+    return getInt32(offset + index * 4);
+  }
+  
+  //24 bytes of pre-defined in between
+  void MVHD::setTrackID(uint32_t newTrackID){
+    if (getVersion() == 0){
+      setInt32(newTrackID, 86);
+    }else{
+      setInt32(newTrackID, 98);
+    }
+  }
+  
+  uint32_t MVHD::getTrackID(){
+    if (getVersion() == 0){
+      return getInt32(86);
+    }else{
+      return getInt32(98);
+    }
+  }
+  
+  std::string MVHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[mvhd] Movie Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl;
+    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
+    r << std::string(indent + 1, ' ') << "Rate: " << getRate() << std::endl;
+    r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl;
+    r << std::string(indent + 1, ' ') << "Matrix: ";
+    for (unsigned int i = 0; i< getMatrixCount(); i++){
+      r << getMatrix(i);
+      if (i!=getMatrixCount()-1){
+        r << ", ";
+      }
+    }
+    r << std::endl;
+    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
+    return r.str();
+  }
+  
+  TFRA::TFRA(){
+    memcpy(data + 4, "dref", 4);
+  }
+  
+  //note, fullbox starts at byte 4
+  void TFRA::setTrackID(uint32_t newTrackID){
+    setInt32(newTrackID, 4);
+  }
+  
+  uint32_t TFRA::getTrackID(){
+    return getInt32(4);
+  }
+  
+  void TFRA::setLengthSizeOfTrafNum(char newVal){
+    char part = getInt8(11);
+    setInt8(((newVal & 0x03)<<4) + (part & 0xCF),11);
+  }
+  
+  char TFRA::getLengthSizeOfTrafNum(){
+    return (getInt8(11)>>4) & 0x03;
+  }
+  
+  void TFRA::setLengthSizeOfTrunNum(char newVal){
+    char part = getInt8(11);
+    setInt8(((newVal & 0x03)<<2) + (part & 0xF3),11);
+  }
+  
+  char TFRA::getLengthSizeOfTrunNum(){
+    return (getInt8(11)>>2) & 0x03;
+  }
+  
+  void TFRA::setLengthSizeOfSampleNum(char newVal){
+    char part = getInt8(11);
+    setInt8(((newVal & 0x03)) + (part & 0xFC),11);
+  }
+  
+  char TFRA::getLengthSizeOfSampleNum(){
+    return (getInt8(11)) & 0x03;
+  }
+  
+  void TFRA::setNumberOfEntry(uint32_t newNumberOfEntry){
+    setInt32(newNumberOfEntry,12);
+  }
+  
+  uint32_t TFRA::getNumberOfEntry(){
+    return getInt32(12);
+  }
+  
+  uint32_t TFRA::getTFRAEntrySize(){
+    int EntrySize= (getVersion()==1 ? 16 : 8);
+    EntrySize += getLengthSizeOfTrafNum()+1;
+    EntrySize += getLengthSizeOfTrunNum()+1;
+    EntrySize += getLengthSizeOfSampleNum()+1;
+    return EntrySize;
+  }
+  
+  void TFRA::setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no){
+    if (no + 1 > getNumberOfEntry()){//if a new entry is issued
+      uint32_t offset = 16 + getTFRAEntrySize() * getNumberOfEntry();//start of filler in bytes
+      uint32_t fillsize = (no + 1 - getNumberOfEntry())*getTFRAEntrySize();//filler in bytes
+      if ( !reserve(offset, 0, fillsize)){//filling space
+        return;
+      }
+      setNumberOfEntry(no+1);
+    }
+    uint32_t loc = 16 + no * getTFRAEntrySize();
+    if (getVersion() == 1){
+      setInt64(newTFRAEntry.time, loc);
+      setInt64(newTFRAEntry.moofOffset, loc+8);
+      loc += 16;
+    }else{
+      setInt32(newTFRAEntry.time, loc);
+      setInt32(newTFRAEntry.moofOffset, loc+4);
+      loc += 8;
+    }
+    switch (getLengthSizeOfTrafNum()){
+      case 0:
+        setInt8(newTFRAEntry.trafNumber, loc);        
+        break;
+      case 1:
+        setInt16(newTFRAEntry.trafNumber, loc);        
+        break;
+      case 2:
+        setInt24(newTFRAEntry.trafNumber, loc);        
+        break;
+      case 3:
+        setInt32(newTFRAEntry.trafNumber, loc);        
+        break;
+    }
+    loc += getLengthSizeOfTrafNum() + 1;
+    switch (getLengthSizeOfTrunNum()){
+      case 0:
+        setInt8(newTFRAEntry.trunNumber, loc);        
+        break;
+      case 1:
+        setInt16(newTFRAEntry.trunNumber, loc);        
+        break;
+      case 2:
+        setInt24(newTFRAEntry.trunNumber, loc);        
+        break;
+      case 3:
+        setInt32(newTFRAEntry.trunNumber, loc);        
+        break;
+    }
+    loc += getLengthSizeOfTrunNum() + 1;
+    switch (getLengthSizeOfSampleNum()){
+      case 0:
+        setInt8(newTFRAEntry.sampleNumber, loc);        
+        break;
+      case 1:
+        setInt16(newTFRAEntry.sampleNumber, loc);        
+        break;
+      case 2:
+        setInt24(newTFRAEntry.sampleNumber, loc);        
+        break;
+      case 3:
+        setInt32(newTFRAEntry.sampleNumber, loc);        
+        break;
+    }
+  }
+  
+  TFRAEntry & TFRA::getTFRAEntry(uint32_t no){
+    static TFRAEntry retval;
+    if (no >= getNumberOfEntry()){
+      static TFRAEntry inval;
+      return inval;
+    }
+    uint32_t loc = 16 + no * getTFRAEntrySize();
+    if (getVersion() == 1){
+      retval.time = getInt64(loc);
+      retval.moofOffset = getInt64(loc + 8);
+      loc += 16;
+    }else{
+      retval.time = getInt32(loc);
+      retval.moofOffset = getInt32(loc + 4);
+      loc += 8;
+    }
+    switch (getLengthSizeOfTrafNum()){
+      case 0:
+        retval.trafNumber = getInt8(loc);        
+        break;
+      case 1:
+        retval.trafNumber = getInt16(loc);        
+        break;
+      case 2:
+        retval.trafNumber = getInt24(loc);        
+        break;
+      case 3:
+        retval.trafNumber = getInt32(loc);        
+        break;
+    }
+    loc += getLengthSizeOfTrafNum() + 1;
+    switch (getLengthSizeOfTrunNum()){
+      case 0:
+        retval.trunNumber = getInt8(loc);        
+        break;
+      case 1:
+        retval.trunNumber = getInt16(loc);        
+        break;
+      case 2:
+        retval.trunNumber = getInt24(loc);        
+        break;
+      case 3:
+        retval.trunNumber = getInt32(loc);        
+        break;
+    }
+    loc += getLengthSizeOfTrunNum() + 1;
+    switch (getLengthSizeOfSampleNum()){
+      case 0:
+        retval.sampleNumber = getInt8(loc);        
+        break;
+      case 1:
+        retval.sampleNumber = getInt16(loc);        
+        break;
+      case 2:
+        retval.sampleNumber = getInt24(loc);        
+        break;
+      case 3:
+        retval.sampleNumber = getInt32(loc);        
+        break;
+    }
+    return retval;
+  }
+       
+  std::string TFRA::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[tfra] Track Fragment Random Access Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
+    r << std::string(indent + 1, ' ') << "lengthSizeOfTrafNum: " << (int)getLengthSizeOfTrafNum() << std::endl;
+    r << std::string(indent + 1, ' ') << "lengthSizeOfTrunNum: " << (int)getLengthSizeOfTrunNum() << std::endl;
+    r << std::string(indent + 1, ' ') << "lengthSizeOfSampleNum: " << (int)getLengthSizeOfSampleNum() << std::endl;
+    r << std::string(indent + 1, ' ') << "NumberOfEntry: " << getNumberOfEntry() << std::endl;
+    for (unsigned int i = 0; i < getNumberOfEntry(); i++){
+      static TFRAEntry temp;
+      temp = getTFRAEntry(i);
+      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
+      r << std::string(indent + 2, ' ') << "Time: " << temp.time << std::endl;
+      r << std::string(indent + 2, ' ') << "MoofOffset: " << temp.moofOffset << std::endl;
+      r << std::string(indent + 2, ' ') << "TrafNumber: " << temp.trafNumber << std::endl;
+      r << std::string(indent + 2, ' ') << "TrunNumber: " << temp.trunNumber << std::endl;
+      r << std::string(indent + 2, ' ') << "SampleNumber: " << temp.sampleNumber << std::endl;
+    }
+    return r.str();
+  }
+
+  TKHD::TKHD(char v, uint32_t f){
+    memcpy(data + 4, "tkhd", 4);
+    setVersion(v);
+    setFlags(f);
+    setCreationTime(0);
+    setModificationTime(0);
+    setTrackID(0);
+    setDuration(0);
+    setLayer(0);
+    setAlternateGroup(0);
+    setVolume(0x0100);
+    setMatrix(0x00010000,0);
+    setMatrix(0x00010000,4);
+    //fills automatically with zero's
+    setMatrix(0x40000000,8);
+    setWidth(0);
+    setHeight(0);
+  }
+  
+  void TKHD::setCreationTime(uint64_t newCreationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newCreationTime, 4);
+    }else{
+      setInt64(newCreationTime, 4);
+    }
+  }
+  
+  uint64_t TKHD::getCreationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(4);
+    }else{
+      return getInt64(4);
+    }
+  }
+  
+  void TKHD::setModificationTime(uint64_t newModificationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newModificationTime, 8);
+    }else{
+      setInt64(newModificationTime, 12);
+    }
+  }
+  
+  uint64_t TKHD::getModificationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(8);
+    }else{
+      return getInt64(12);
+    }
+  }
+  
+  void TKHD::setTrackID(uint32_t newTrackID){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newTrackID, 12);
+    }else{
+      setInt32(newTrackID, 20);
+    }
+  }
+  
+  uint32_t TKHD::getTrackID(){
+    if (getVersion() == 0){
+      return getInt32(12);
+    }else{
+      return getInt32(20);
+    }
+  }
+  //note 4 bytes reserved in between
+  void TKHD::setDuration(uint64_t newDuration){
+    if (getVersion() == 0){
+      setInt32(newDuration, 20);
+    }else{
+      setInt64(newDuration, 28);
+    }
+  }
+  
+  uint64_t TKHD::getDuration(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(20);
+    }else{
+      return getInt64(28);
+    }
+  }
+  //8 bytes reserved in between
+  void TKHD::setLayer(uint16_t newLayer){
+    if (getVersion() == 0){
+      setInt16(newLayer, 32);
+    }else{
+      setInt16(newLayer, 44);
+    }
+  }
+  
+  uint16_t TKHD::getLayer(){
+    if (getVersion() == 0){
+      return getInt16(32);
+    }else{
+      return getInt16(44);
+    }
+  }
+  
+  void TKHD::setAlternateGroup(uint16_t newAlternateGroup){
+    if (getVersion() == 0){
+      setInt16(newAlternateGroup, 34);
+    }else{
+      setInt16(newAlternateGroup, 46);
+    }
+  }
+  
+  uint16_t TKHD::getAlternateGroup(){
+    if (getVersion() == 0){
+      return getInt16(34);
+    }else{
+      return getInt16(46);
+    }
+  }
+  
+  void TKHD::setVolume(uint16_t newVolume){
+    if (getVersion() == 0){
+      setInt16(newVolume, 36);
+    }else{
+      setInt16(newVolume, 48);
+    }
+  }
+  
+  uint16_t TKHD::getVolume(){
+    if (getVersion() == 0){
+      return getInt16(36);
+    }else{
+      return getInt16(48);
+    }
+  }
+  //2 bytes reserved in between
+  uint32_t TKHD::getMatrixCount(){
+    return 9;
+  }
+  
+  void TKHD::setMatrix(int32_t newMatrix, size_t index){
+    int offset = 0;
+    if (getVersion() == 0){
+      offset = 36 + 2 + 2;
+    }else{
+      offset = 48 + 2 + 2;
+    }
+    setInt32(newMatrix, offset + index * 4);
+  }
+  
+  int32_t TKHD::getMatrix(size_t index){
+    int offset = 0;
+    if (getVersion() == 0){
+      offset = 36 + 2 + 2;
+    }else{
+      offset = 48 + 2 + 2;
+    }
+    return getInt32(offset + index * 4);
+  }
+  
+  void TKHD::setWidth(uint32_t newWidth){
+    if (getVersion() == 0){
+      setInt32(newWidth, 76);
+    }else{
+      setInt32(newWidth, 88);
+    }
+  }
+  
+  uint32_t TKHD::getWidth(){
+    if (getVersion() == 0){
+      return getInt32(76);
+    }else{
+      return getInt32(88);
+    }
+  }
+  
+  void TKHD::setHeight(uint32_t newHeight){
+    if (getVersion() == 0){
+      setInt32(newHeight, 80);
+    }else{
+      setInt32(newHeight, 92);
+    }
+  }
+  
+  uint32_t TKHD::getHeight(){
+    if (getVersion() == 0){
+      return getInt32(80);
+    }else{
+      return getInt32(92);
+    }
+  }
+        
+  std::string TKHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[tkhd] Track Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
+    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
+    r << std::string(indent + 1, ' ') << "Layer: " << getLayer() << std::endl;
+    r << std::string(indent + 1, ' ') << "AlternateGroup: " << getAlternateGroup() << std::endl;
+    r << std::string(indent + 1, ' ') << "Volume: " << getVolume() << std::endl;
+    r << std::string(indent + 1, ' ') << "Matrix: ";
+    for (unsigned int i = 0; i< getMatrixCount(); i++){
+      r << getMatrix(i);
+      if (i!=getMatrixCount()-1){
+        r << ", ";
+      }
+    }
+    r << std::endl;
+    r << std::string(indent + 1, ' ') << "Width: " << (getWidth() >> 16) << "." << (getWidth() & 0xFFFF) << std::endl;
+    r << std::string(indent + 1, ' ') << "Height: " << (getHeight() >> 16) << "." << (getHeight() & 0xFFFF) << std::endl;
+    return r.str();
+  }
+
+  MDHD::MDHD(char v, uint32_t f){
+    memcpy(data + 4, "mdhd", 4);
+    setVersion(v);
+    setFlags(f);
+    setCreationTime(0);
+    setModificationTime(0);
+    setTimeScale(1000);
+    setDuration(0);
+    setLanguage(0);
+    if (v==0){
+      setInt16(0,22);
+    }else{
+      setInt16(0,34);
+    }
+  }
+  
+  void MDHD::setCreationTime(uint64_t newCreationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newCreationTime, 4);
+    }else{
+      setInt64(newCreationTime, 4);
+    }
+  }
+  
+  uint64_t MDHD::getCreationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(4);
+    }else{
+      return getInt64(4);
+    }
+  }
+  
+  void MDHD::setModificationTime(uint64_t newModificationTime){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newModificationTime, 8);
+    }else{
+      setInt64(newModificationTime, 12);
+    }
+  }
+  
+  uint64_t MDHD::getModificationTime(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(8);
+    }else{
+      return getInt64(12);
+    }
+  }
+  
+  void MDHD::setTimeScale(uint32_t newTimeScale){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newTimeScale, 12);
+    }else{
+      setInt32(newTimeScale, 20);
+    }
+  }
+  
+  uint32_t MDHD::getTimeScale(){
+    if (getVersion() == 0){
+      return getInt32(12);
+    }else{
+      return getInt32(20);
+    }
+  }
+  
+  void MDHD::setDuration(uint64_t newDuration){
+    if (getVersion() == 0){
+      setInt32((uint32_t) newDuration, 16);
+    }else{
+      setInt64(newDuration, 24);
+    }
+  }
+  
+  uint64_t MDHD::getDuration(){
+    if (getVersion() == 0){
+      return (uint64_t)getInt32(16);
+    }else{
+      return getInt64(24);
+    }
+  }
+
+  void MDHD::setLanguage (uint16_t newLanguage){
+    if (getVersion() == 0){
+      setInt16(newLanguage & 0x7F, 20);
+    }else{
+      setInt16(newLanguage & 0x7F, 32);
+    }
+  }
+  
+  uint16_t MDHD::getLanguage(){
+    if (getVersion() == 0){
+      return getInt16(20) & 0x7F;
+    }else{
+      return getInt16(32) & 0x7F;
+    }
+  }
+  
+  std::string MDHD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[mdhd] Media Header Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "CreationTime: " << getCreationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "ModificationTime: " << getModificationTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "TimeScale: " << getTimeScale() << std::endl;
+    r << std::string(indent + 1, ' ') << "Duration: " << getDuration() << std::endl;
+    r << std::string(indent + 1, ' ') << "Language: 0x" << std::hex << getLanguage() << std::dec<< std::endl;
+    return r.str();
+  }
+  
+  STTS::STTS(char v, uint32_t f){
+    memcpy(data + 4, "stts", 4);
+    setVersion(v);
+    setFlags(f);
+    setEntryCount(0);
+  }
+  
+  void STTS::setEntryCount(uint32_t newEntryCount){
+    setInt32(newEntryCount, 4);
+  }
+  
+  uint32_t STTS::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void STTS::setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no){
+    if(no + 1 > getEntryCount()){
+      setEntryCount(no + 1);
+      for (unsigned int i = getEntryCount(); i < no; i++){
+        setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits
+      }
+    }
+    setInt32(newSTTSEntry.sampleCount, 8 + no * 8);
+    setInt32(newSTTSEntry.sampleDelta, 8 + (no * 8) + 4);
+  }
+  
+  STTSEntry STTS::getSTTSEntry(uint32_t no){
+    static STTSEntry retval;
+    if (no >= getEntryCount()){
+      static STTSEntry inval;
+      return inval;
+    }
+    retval.sampleCount = getInt32(8 + (no * 8));
+    retval.sampleDelta = getInt32(8 + (no * 8) + 4);
+    return retval;
+  }
+  
+  std::string STTS::toPrettyString(uint32_t indent){
+      std::stringstream r;
+    r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      static STTSEntry temp;
+      temp = getSTTSEntry(i);
+      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
+      r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl;
+      r << std::string(indent + 2, ' ') << "SampleDelta: " << temp.sampleDelta << std::endl;
+    }
+    return r.str();
+
+  }
+  
+  CTTS::CTTS(){
+    memcpy(data + 4, "ctts", 4);
+  }
+  
+  void CTTS::setEntryCount(uint32_t newEntryCount){
+    setInt32(newEntryCount, 4);
+  }
+  
+  uint32_t CTTS::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void CTTS::setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no){
+    if(no + 1 > getEntryCount()){
+      for (unsigned int i = getEntryCount(); i < no; i++){
+        setInt64(0, 8 + (i * 8));//filling up undefined entries of 64 bits
+      }
+    }
+    setInt32(newCTTSEntry.sampleCount, 8 + no * 8);
+    setInt32(newCTTSEntry.sampleOffset, 8 + (no * 8) + 4);
+  }
+  
+  CTTSEntry CTTS::getCTTSEntry(uint32_t no){
+    static CTTSEntry retval;
+    if (no >= getEntryCount()){
+      static CTTSEntry inval;
+      return inval;
+    }
+    retval.sampleCount = getInt32(8 + (no * 8));
+    retval.sampleOffset = getInt32(8 + (no * 8) + 4);
+    return retval;
+  }
+  
+  std::string CTTS::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stts] Sample Table Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      static CTTSEntry temp;
+      temp = getCTTSEntry(i);
+      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
+      r << std::string(indent + 2, ' ') << "SampleCount: " << temp.sampleCount << std::endl;
+      r << std::string(indent + 2, ' ') << "SampleOffset: " << temp.sampleOffset << std::endl;
+    }
+    return r.str();
+
+  }
+
+  STSC::STSC(char v, uint32_t f){
+    memcpy(data + 4, "stsc", 4);
+    setVersion(v);
+    setFlags(f);
+    setEntryCount(0);
+  }
+  
+  void STSC::setEntryCount(uint32_t newEntryCount){
+    setInt32(newEntryCount, 4);
+  }
+  
+  uint32_t STSC::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void STSC::setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no){
+    if(no + 1 > getEntryCount()){
+      setEntryCount(no+1);
+      for (unsigned int i = getEntryCount(); i < no; i++){
+        setInt64(0, 8 + (i * 12));//filling up undefined entries of 64 bits
+        setInt32(0, 8 + (i * 12) + 8);
+      }
+    }
+    setInt32(newSTSCEntry.firstChunk, 8 + no * 12);
+    setInt32(newSTSCEntry.samplesPerChunk, 8 + (no * 12) + 4);
+    setInt32(newSTSCEntry.sampleDescriptionIndex, 8 + (no * 12) + 8);
+  }
+  
+  STSCEntry STSC::getSTSCEntry(uint32_t no){
+    static STSCEntry retval;
+    if (no >= getEntryCount()){
+      static STSCEntry inval;
+      return inval;
+    }
+    retval.firstChunk = getInt32(8 + (no * 12));
+    retval.samplesPerChunk = getInt32(8 + (no * 12) + 4);
+    retval.sampleDescriptionIndex = getInt32(8 + (no * 12) + 8);
+    return retval;
+  }
+  
+  std::string STSC::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stsc] Sample To Chunk Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      static STSCEntry temp;
+      temp = getSTSCEntry(i);
+      r << std::string(indent + 1, ' ') << "Entry[" << i <<"]:"<< std::endl;
+      r << std::string(indent + 2, ' ') << "FirstChunk: " << temp.firstChunk << std::endl;
+      r << std::string(indent + 2, ' ') << "SamplesPerChunk: " << temp.samplesPerChunk << std::endl;
+      r << std::string(indent + 2, ' ') << "SampleDescriptionIndex: " << temp.sampleDescriptionIndex << std::endl;
+    }
+    return r.str();
+  }
+  
+  STCO::STCO(char v, uint32_t f){
+    memcpy(data + 4, "stco", 4);
+    setVersion(v);
+    setFlags(f);
+    setEntryCount(0);
+  }
+  
+  void STCO::setEntryCount(uint32_t newEntryCount){
+    setInt32(newEntryCount, 4);
+  }
+  
+  uint32_t STCO::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void STCO::setChunkOffset(uint32_t newChunkOffset, uint32_t no){
+    if (no + 1 > getEntryCount()){
+      for (unsigned int i = getEntryCount(); i < no; i++){
+        setInt32(0, 8 + i * 4);//filling undefined entries
+      }
+      setEntryCount(no+1);
+    }
+    setInt32(newChunkOffset, 8 + no * 4);  
+  }
+  
+  uint32_t STCO::getChunkOffset(uint32_t no){
+    if (no >= getEntryCount()){
+      return 0;
+    }
+    return getInt32(8 + no * 4);
+  }
+  
+  std::string STCO::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stco] Chunk Offset Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      r << std::string(indent + 1, ' ') << "ChunkOffset[" << i <<"]: " << getChunkOffset(i) << std::endl;
+    }
+    return r.str();
+  }
+
+  STSZ::STSZ(char v, uint32_t f){
+    memcpy(data + 4, "stsz", 4);
+    setVersion(v);
+    setFlags(f);
+    setSampleCount(0);
+  }
+
+  void STSZ::setSampleSize(uint32_t newSampleSize){
+    setInt32(newSampleSize, 4);
+  }
+  
+  uint32_t STSZ::getSampleSize(){
+    return getInt32(4);
+  }
+  
+  void STSZ::setSampleCount(uint32_t newSampleCount){
+    setInt32(newSampleCount, 8);
+  }
+  
+  uint32_t STSZ::getSampleCount(){
+    return getInt32(8);
+  }
+  
+  void STSZ::setEntrySize(uint32_t newEntrySize, uint32_t no){
+    if (no + 1 > getSampleCount()){
+      setSampleCount(no + 1);
+      for (unsigned int i = getSampleCount(); i < no; i++){
+        setInt32(0, 12 + i * 4);//filling undefined entries
+      }
+    }
+    setInt32(newEntrySize, 12 + no * 4);
+  }
+  
+  uint32_t STSZ::getEntrySize(uint32_t no){
+    if (no >= getSampleCount()){
+      return 0;
+    }
+    return getInt32(12 + no * 4);
+  }
+  
+  std::string STSZ::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stsz] Sample Size Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl;
+    r << std::string(indent + 1, ' ') << "SampleCount: " << getSampleCount() << std::endl;
+    for (unsigned int i = 0; i < getSampleCount(); i++){
+      r << std::string(indent + 1, ' ') << "EntrySize[" << i <<"]: " << getEntrySize(i) << std::endl;
+    }
+    return r.str();
+  }
+
+  SampleEntry::SampleEntry(){
+    memcpy(data + 4, "erro", 4);
+  }
+  
+  void SampleEntry::setDataReferenceIndex(uint16_t newDataReferenceIndex){
+    setInt16(newDataReferenceIndex, 6);
+  }
+  
+  uint16_t SampleEntry::getDataReferenceIndex(){
+    return getInt16(6);
+  }
+  
+  std::string SampleEntry::toPrettySampleString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent + 1, ' ') << "DataReferenceIndex: " << getDataReferenceIndex() << std::endl;
+    return r.str();  
+  }
+
+  CLAP::CLAP(){
+    memcpy(data + 4, "clap", 4);
+    setHorizOffN(0);
+    setHorizOffD(0);
+    setVertOffN(0);
+    setVertOffD(0);
+  }
+  
+  void CLAP::setCleanApertureWidthN(uint32_t newVal){
+    setInt32(newVal,0);  
+  }
+  
+  uint32_t CLAP::getCleanApertureWidthN(){
+    return getInt32(0);
+  }
+  
+  void CLAP::setCleanApertureWidthD(uint32_t newVal){
+    setInt32(newVal,4);
+  }
+  
+  uint32_t CLAP::getCleanApertureWidthD(){
+    return getInt32(4);
+  }
+  
+  void CLAP::setCleanApertureHeightN(uint32_t newVal){
+    setInt32(newVal,8);
+  }
+  
+  uint32_t CLAP::getCleanApertureHeightN(){
+    return getInt32(8);
+  }
+  
+  void CLAP::setCleanApertureHeightD(uint32_t newVal){
+    setInt32(newVal, 12);
+  }
+  
+  uint32_t CLAP::getCleanApertureHeightD(){
+    return getInt32(12);
+  }
+  
+  void CLAP::setHorizOffN(uint32_t newVal){
+    setInt32(newVal, 16);
+  }
+  
+  uint32_t CLAP::getHorizOffN(){
+    return getInt32(16);
+  }
+  
+  void CLAP::setHorizOffD(uint32_t newVal){
+    setInt32(newVal, 20);
+  }
+  
+  uint32_t CLAP::getHorizOffD(){
+    return getInt32(20);
+  }
+  
+  void CLAP::setVertOffN(uint32_t newVal){
+    setInt32(newVal, 24);
+  }
+  
+  uint32_t CLAP::getVertOffN(){
+    return getInt32(24);
+  }
+  
+  void CLAP::setVertOffD(uint32_t newVal){
+    setInt32(newVal, 28);
+  }
+  
+  uint32_t CLAP::getVertOffD(){
+    return getInt32(32);
+  }
+  
+  std::string CLAP::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[clap] Clean Aperture Box (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "CleanApertureWidthN: " << getCleanApertureWidthN() << std::endl;
+    r << std::string(indent + 1, ' ') << "CleanApertureWidthD: " << getCleanApertureWidthD() << std::endl;
+    r << std::string(indent + 1, ' ') << "CleanApertureHeightN: " << getCleanApertureHeightN() << std::endl;
+    r << std::string(indent + 1, ' ') << "CleanApertureHeightD: " << getCleanApertureHeightD() << std::endl;
+    r << std::string(indent + 1, ' ') << "HorizOffN: " << getHorizOffN() << std::endl;
+    r << std::string(indent + 1, ' ') << "HorizOffD: " << getHorizOffD() << std::endl;
+    r << std::string(indent + 1, ' ') << "VertOffN: " << getVertOffN() << std::endl;
+    r << std::string(indent + 1, ' ') << "VertOffD: " << getVertOffD() << std::endl;
+    return r.str();
+  }
+  
+  PASP::PASP(){
+    memcpy(data + 4, "pasp", 4);
+  }
+  
+  void PASP::setHSpacing(uint32_t newVal){
+    setInt32(newVal, 0);
+  }
+  
+  uint32_t PASP::getHSpacing(){
+    return getInt32(0);
+  }
+  
+  void PASP::setVSpacing(uint32_t newVal){
+    setInt32(newVal, 4);
+  }
+  
+  uint32_t PASP::getVSpacing(){
+    return getInt32(4);
+  }
+  
+  std::string PASP::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[pasp] Pixel Aspect Ratio Box (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "HSpacing: " << getHSpacing() << std::endl;
+    r << std::string(indent + 1, ' ') << "VSpacing: " << getVSpacing() << std::endl;
+    return r.str();
+  }
+
+  VisualSampleEntry::VisualSampleEntry(){
+    memcpy(data + 4, "erro", 4);
+    setHorizResolution(0x00480000);
+    setVertResolution(0x00480000);
+    setFrameCount(1);
+    setCompressorName("");
+    setDepth(0x0018);
+  }
+  
+  void VisualSampleEntry::setCodec(const char* newCodec){
+    memcpy(data + 4, newCodec, 4);
+  }
+  
+  void VisualSampleEntry::setWidth(uint16_t newWidth){
+    setInt16(newWidth,24);
+  }
+  
+  uint16_t VisualSampleEntry::getWidth(){
+    return getInt16(24);
+  }
+  
+  void VisualSampleEntry::setHeight(uint16_t newHeight){
+    setInt16(newHeight, 26);
+  }
+  
+  uint16_t VisualSampleEntry::getHeight(){
+    return getInt16(26);
+  }
+  
+  void VisualSampleEntry::setHorizResolution (uint32_t newHorizResolution){
+    setInt32(newHorizResolution, 28);
+  }
+  
+  uint32_t VisualSampleEntry::getHorizResolution(){
+    return getInt32(28);
+  }
+  
+  void VisualSampleEntry::setVertResolution (uint32_t newVertResolution){
+    setInt32(newVertResolution,32);
+  }
+  
+  uint32_t VisualSampleEntry::getVertResolution(){
+    return getInt32(32);
+  }
+  
+  void VisualSampleEntry::setFrameCount(uint16_t newFrameCount){
+    setInt16(newFrameCount, 40);
+  }
+  
+  uint16_t VisualSampleEntry::getFrameCount(){
+    return getInt16(40);
+  }
+
+  void VisualSampleEntry::setCompressorName(std::string newCompressorName){
+    newCompressorName.resize(32, ' ');
+    setString(newCompressorName,42);
+  }
+  
+  std::string VisualSampleEntry::getCompressorName(){
+    return getString(42);
+  }
+
+  void VisualSampleEntry::setDepth(uint16_t newDepth){
+    setInt16(newDepth, 74);
+  }
+  
+  uint16_t VisualSampleEntry::getDepth(){
+    return getInt16(74);
+  }
+
+  void VisualSampleEntry::setCLAP(Box& clap){
+    setBox(clap,78);
+  }
+
+  Box & VisualSampleEntry::getCLAP(){
+    static Box ret = Box((char*)"\000\000\000\010erro", false);
+    if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP
+      return ret;
+    }
+    ret = getBox(78);
+    return ret;
+  }
+  
+  Box & VisualSampleEntry::getPASP(){
+    static Box ret = Box((char*)"\000\000\000\010erro", false);
+    if(payloadSize() <84){//if the EntryBox is not big enough to hold a CLAP/PASP
+      return ret;
+    }
+    if (payloadSize() < 78 + getBoxLen(78) + 8){
+      return ret;
+    }else{
+      return getBox(78+getBoxLen(78));
+    }
+    
+  }
+  
+  std::string VisualSampleEntry::toPrettyVisualString(uint32_t indent, std::string name){
+    std::stringstream r;
+    r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl;
+    r << toPrettySampleString(indent);
+    r << std::string(indent + 1, ' ') << "Width: " << getWidth() << std::endl;
+    r << std::string(indent + 1, ' ') << "Height: " << getHeight() << std::endl;
+    r << std::string(indent + 1, ' ') << "HorizResolution: " << getHorizResolution() << std::endl;
+    r << std::string(indent + 1, ' ') << "VertResolution: " << getVertResolution() << std::endl;
+    r << std::string(indent + 1, ' ') << "FrameCount: " << getFrameCount() << std::endl;
+    r << std::string(indent + 1, ' ') << "CompressorName: " << getCompressorName() << std::endl;
+    r << std::string(indent + 1, ' ') << "Depth: " << getDepth() << std::endl;
+    if (!getCLAP().isType("erro")){
+      r << getCLAP().toPrettyString(indent+1);
+    }
+    if (!getPASP().isType("erro")){
+      r << getPASP().toPrettyString(indent+1);
+    }
+    return r.str();
+  }
+
+  AudioSampleEntry::AudioSampleEntry(){
+    memcpy(data + 4, "erro", 4);
+    setChannelCount(2);
+    setSampleSize(16);
+    setSampleRate(44100);
+  }
+
+  void AudioSampleEntry::setCodec(const char* newCodec){
+    memcpy(data + 4, newCodec, 4);
+  }
+  
+  void AudioSampleEntry::setChannelCount(uint16_t newChannelCount){
+    setInt16(newChannelCount,16);
+  }
+  
+  uint16_t AudioSampleEntry::getChannelCount(){
+    return getInt16(16);
+  }
+  
+  void AudioSampleEntry::setSampleSize(uint16_t newSampleSize){
+    setInt16(newSampleSize,18);
+  }
+  
+  uint16_t AudioSampleEntry::getSampleSize(){
+    return getInt16(18);
+  }
+  
+  void AudioSampleEntry::setPreDefined(uint16_t newPreDefined){
+    setInt16(newPreDefined,20);
+  }
+  
+  uint16_t AudioSampleEntry::getPreDefined(){
+    return getInt16(20);
+  }
+  
+  void AudioSampleEntry::setSampleRate(uint32_t newSampleRate){
+    setInt32(newSampleRate << 16, 24);
+  }
+  
+  uint32_t AudioSampleEntry::getSampleRate(){
+    return getInt32(24) >> 16;
+  }
+  
+  void AudioSampleEntry::setCodecBox(Box& newBox){
+    setBox(newBox, 28);
+  }
+  
+  Box & AudioSampleEntry::getCodecBox(){
+    return getBox(28);
+  }
+  
+  std::string AudioSampleEntry::toPrettyAudioString(uint32_t indent, std::string name){
+    std::stringstream r;
+    r << std::string(indent, ' ') << name << " (" << boxedSize() << ")" << std::endl;
+    r << toPrettySampleString(indent);
+    r << std::string(indent + 1, ' ') << "ChannelCount: " << getChannelCount() << std::endl;
+    r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl;
+    r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl;
+    r << std::string(indent + 1, ' ') << "SampleRate: " << getSampleRate() << std::endl;
+    r << getCodecBox().toPrettyString(indent + 1) << std::endl;
+    return r.str();
+  }
+
+  MP4A::MP4A(){
+    memcpy(data + 4, "mp4a", 4);
+  }
+  
+  std::string MP4A::toPrettyString(uint32_t indent){
+    return toPrettyAudioString(indent, "[mp4a] MPEG-4 Audio");
+  }
+
+  AAC::AAC(){
+    memcpy(data + 4, "aac ", 4);
+  }
+  
+  std::string AAC::toPrettyString(uint32_t indent){
+    return toPrettyAudioString(indent, "[aac ] Advanced Audio Codec");
+  }
+
+  AVC1::AVC1(){
+    memcpy(data + 4, "avc1", 4);
+  }
+  
+  std::string AVC1::toPrettyString(uint32_t indent){
+    return toPrettyVisualString(indent, "[avc1] Advanced Video Codec 1");
+  }
+
+  H264::H264(){
+    memcpy(data + 4, "h264", 4);
+  }
+  
+  std::string H264::toPrettyString(uint32_t indent){
+    return toPrettyVisualString(indent, "[h264] H.264/MPEG-4 AVC");
+  }
+
+  STSD::STSD(char v, uint32_t f){
+    memcpy(data + 4, "stsd", 4);
+    setVersion(v);
+    setFlags(f);
+    setEntryCount(0);
+  }
+
+  void STSD::setEntryCount (uint32_t newEntryCount){
+    setInt32(newEntryCount, 4);
+  }
+  
+  uint32_t STSD::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void STSD::setEntry(Box & newContent, uint32_t no){
+  int tempLoc = 8;
+    unsigned int entryCount = getEntryCount();
+    for (unsigned int i = 0; i < no; i++){
+      if (i < entryCount){
+        tempLoc += getBoxLen(tempLoc);
+      }else{
+        if ( !reserve(tempLoc, 0, (no - entryCount) * 8)){
+          return;
+        }
+        memset(data + tempLoc, 0, (no - entryCount) * 8);
+        tempLoc += (no - entryCount) * 8;
+        break;
+      }
+    }
+    setBox(newContent, tempLoc);
+    if (getEntryCount() < no+1){
+      setEntryCount(no+1);
+    }
+  }
+  
+  Box & STSD::getEntry(uint32_t no){
+    static Box ret = Box((char*)"\000\000\000\010erro", false);
+    if (no > getEntryCount()){
+      return ret;
+    }
+    unsigned int i = 0;
+    int tempLoc = 8;
+    while (i < no){
+      tempLoc += getBoxLen(tempLoc);
+      i++;
+    }
+    return getBox(tempLoc);
+  }
+
+  std::string STSD::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stsd] Sample Description Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntrySize: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      Box curBox = Box(getEntry(i).asBox(), false);
+      r << curBox.toPrettyString(indent + 1);
+    }
+    return r.str();
+  }
+
+  EDTS::EDTS(){
+    memcpy(data + 4, "edts", 4);
+  }
+
+  UDTA::UDTA(){
+    memcpy(data + 4, "udta", 4);
+  }
+
+  STSS::STSS(char v, uint32_t f){
+    memcpy(data + 4, "stss", 4);
+    setVersion(v);
+    setFlags(f);
+    setEntryCount(0);
+  }
+  
+  void STSS::setEntryCount(uint32_t newVal){
+    setInt32(newVal, 4);
+  }
+  
+  uint32_t STSS::getEntryCount(){
+    return getInt32(4);
+  }
+  
+  void STSS::setSampleNumber(uint32_t newVal, uint32_t index){
+    if (index >= getEntryCount()){
+      setEntryCount(index + 1);
+    }
+    setInt32(newVal, 8 + (index * 4));
+  }
+  
+  uint32_t STSS::getSampleNumber(uint32_t index){
+    if (index >= getEntryCount()){
+      return 0;
+    }
+    return getInt32(8 + (index * 4));
+  }
+  
+  std::string STSS::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[stss] Sync Sample Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "EntryCount: " << getEntryCount() << std::endl;
+    for (unsigned int i = 0; i < getEntryCount(); i++){
+      r << std::string(indent + 1, ' ') << "SampleNumber[" << i <<"] : " << getSampleNumber(i) << std::endl;
+    }
+    return r.str();
+  }
+
+  META::META(){
+    memcpy(data + 4, "meta", 4);
+  }
+  
+  std::string META::toPrettyString(uint32_t indent){
+    return toPrettyCFBString(indent, "[meta] Meta Box");
+  }
+
+  ELST::ELST(){
+    memcpy(data + 4, "elst", 4);
+  }
+  
+  void ELST::setSegmentDuration(uint64_t newVal){
+    if (getVersion() == 1){
+      setInt64(newVal, 4);
+    }else{
+      setInt32(newVal, 4);
+    }
+  }
+  
+  uint64_t ELST::getSegmentDuration(){
+    if (getVersion() == 1){
+      return getInt64(4);
+    }else{
+      return getInt32(4);
+    }
+  }
+  
+  void ELST::setMediaTime(uint64_t newVal){
+    if (getVersion() == 1){
+      setInt64(newVal, 12);
+    }else{
+      setInt32(newVal, 8);
+    }
+  }
+  
+  uint64_t ELST::getMediaTime(){
+    if (getVersion() == 1){
+      return getInt64(12);
+    }else{
+      return getInt32(8);
+    }
+  }
+  
+  void ELST::setMediaRateInteger(uint16_t newVal){
+    if (getVersion() == 1){
+      setInt16(newVal, 20);
+    }else{
+      setInt16(newVal, 12);
+    }
+  }
+  
+  uint16_t ELST::getMediaRateInteger(){
+    if (getVersion() == 1){
+      return getInt16(20);
+    }else{
+      return getInt16(12);
+    }
+  }
+  
+  void ELST::setMediaRateFraction(uint16_t newVal){
+    if (getVersion() == 1){
+      setInt16(newVal, 22);
+    }else{
+      setInt16(newVal, 14);
+    }
+  }
+  
+  uint16_t ELST::getMediaRateFraction(){
+    if (getVersion() == 1){
+      return getInt16(22);
+    }else{
+      return getInt16(14);
+    }
+  }
+  
+  std::string ELST::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl;
+    r << fullBox::toPrettyString(indent);
+    r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl;
+    r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl;
+    r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl;
+    r << std::string(indent + 1, ' ') << "MediaRateFraction: " << getMediaRateFraction() << std::endl;
+    return r.str();
+  }
+}
diff --git a/lib/mp4_generic.h b/lib/mp4_generic.h
new file mode 100644
index 00000000..f66667bc
--- /dev/null
+++ b/lib/mp4_generic.h
@@ -0,0 +1,674 @@
+#include "mp4.h"
+
+namespace MP4{
+  class MFHD: public Box{
+    public:
+      MFHD();
+      void setSequenceNumber(uint32_t newSequenceNumber);
+      uint32_t getSequenceNumber();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  //MFHD Box
+
+  class MOOF: public containerBox{
+    public:
+      MOOF();
+  };
+  //MOOF Box
+
+  class TRAF: public Box{
+    public:
+      TRAF();
+      uint32_t getContentCount();
+      void setContent(Box & newContent, uint32_t no);
+      Box & getContent(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  //TRAF Box
+
+  struct trunSampleInformation{
+      uint32_t sampleDuration;
+      uint32_t sampleSize;
+      uint32_t sampleFlags;
+      uint32_t sampleOffset;
+  };
+  enum trunflags{
+    trundataOffset = 0x00000001,
+    trunfirstSampleFlags = 0x00000004,
+    trunsampleDuration = 0x00000100,
+    trunsampleSize = 0x00000200,
+    trunsampleFlags = 0x00000400,
+    trunsampleOffsets = 0x00000800
+  };
+  enum sampleflags{
+    noIPicture = 0x01000000,
+    isIPicture = 0x02000000,
+    noDisposable = 0x00400000,
+    isDisposable = 0x00800000,
+    isRedundant = 0x00100000,
+    noRedundant = 0x00200000,
+    noKeySample = 0x00010000,
+    isKeySample = 0x00000000,
+    MUST_BE_PRESENT = 0x1
+  };
+  std::string prettySampleFlags(uint32_t flag);
+  class TRUN: public Box{
+    public:
+      TRUN();
+      void setFlags(uint32_t newFlags);
+      uint32_t getFlags();
+      void setDataOffset(uint32_t newOffset);
+      uint32_t getDataOffset();
+      void setFirstSampleFlags(uint32_t newSampleFlags);
+      uint32_t getFirstSampleFlags();
+      uint32_t getSampleInformationCount();
+      void setSampleInformation(trunSampleInformation newSample, uint32_t no);
+      trunSampleInformation getSampleInformation(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  enum tfhdflags{
+    tfhdBaseOffset = 0x000001,
+    tfhdSampleDesc = 0x000002,
+    tfhdSampleDura = 0x000008,
+    tfhdSampleSize = 0x000010,
+    tfhdSampleFlag = 0x000020,
+    tfhdNoDuration = 0x010000,
+  };
+  class TFHD: public Box{
+    public:
+      TFHD();
+      void setFlags(uint32_t newFlags);
+      uint32_t getFlags();
+      void setTrackID(uint32_t newID);
+      uint32_t getTrackID();
+      void setBaseDataOffset(uint64_t newOffset);
+      uint64_t getBaseDataOffset();
+      void setSampleDescriptionIndex(uint32_t newIndex);
+      uint32_t getSampleDescriptionIndex();
+      void setDefaultSampleDuration(uint32_t newDuration);
+      uint32_t getDefaultSampleDuration();
+      void setDefaultSampleSize(uint32_t newSize);
+      uint32_t getDefaultSampleSize();
+      void setDefaultSampleFlags(uint32_t newFlags);
+      uint32_t getDefaultSampleFlags();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+
+  class AVCC: public Box{
+    public:
+      AVCC();
+      void setVersion(uint32_t newVersion);
+      uint32_t getVersion();
+      void setProfile(uint32_t newProfile);
+      uint32_t getProfile();
+      void setCompatibleProfiles(uint32_t newCompatibleProfiles);
+      uint32_t getCompatibleProfiles();
+      void setLevel(uint32_t newLevel);
+      uint32_t getLevel();
+      void setSPSNumber(uint32_t newSPSNumber);
+      uint32_t getSPSNumber();
+      void setSPS(std::string newSPS);
+      uint32_t getSPSLen();
+      char* getSPS();
+      void setPPSNumber(uint32_t newPPSNumber);
+      uint32_t getPPSNumber();
+      void setPPS(std::string newPPS);
+      uint32_t getPPSLen();
+      char* getPPS();
+      std::string asAnnexB();
+      void setPayload(std::string newPayload);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  ///\todo : ESDS is filthy implemented, clean up when optimising
+  class ESDS: public fullBox{
+    public:
+      ESDS();
+      ESDS(std::string init, uint32_t bps);
+      char getESDescriptorType();
+      void setESDescriptorType(char newVal);
+      uint32_t getExtendedESDescriptorType();//3 bytes
+      void setExtendedESDescriptorType(uint32_t newVal);//3 bytes
+      char getESDescriptorTypeLength();
+      void setESDescriptorTypeLength(char newVal);
+      //ESID 2 bytes
+      uint16_t getESID();
+      void setESID(uint16_t newVal);
+      //stream priority 1 byte
+      char getStreamPriority();
+      void setStreamPriority(char newVal);
+      //decoder config descriptor tag 1byte
+      char getDecoderConfigDescriptorTag();
+      void setDecoderConfigDescriptorTag(char newVal);
+      //extended decoder config descriptor tag 3 bytes
+      uint32_t getExtendedDecoderConfigDescriptorTag();
+      void setExtendedDecoderConfigDescriptorTag(uint32_t newVal);//3 bytes
+      //decoder config descriptor type length
+      char getDecoderConfigDescriptorTypeLength();
+      void setDecoderConfigDescriptorTypeLength(char newVal);
+      char getByteObjectTypeID();
+      void setByteObjectTypeID(char newVal);
+      char getStreamType();//6 bits
+      void setStreamType(char newVal);//6 bits
+      bool getUpstreamFlag();
+      void setUpstreamFlag(bool newVal);
+      bool getReservedFlag();
+      void setReservedFlag(bool newVal);
+      uint32_t getBufferSize();//3 bytes
+      void setBufferSize(uint32_t newVal);//3 bytes
+      uint32_t getMaximumBitRate();
+      void setMaximumBitRate(uint32_t newVal);
+      uint32_t getAverageBitRate();
+      void setAverageBitRate(uint32_t newVal);
+      char getDecoderDescriptorTypeTag();
+      void setDecoderDescriptorTypeTag(char newVal);
+      uint32_t getExtendedDecoderDescriptorTypeTag();//3 bytes
+      void setExtendedDecoderDescriptorTypeTag(uint32_t newVal);//3 bytes
+      char getConfigDescriptorTypeLength();
+      void setConfigDescriptorTypeLength(char newVal);
+      std::string getESHeaderStartCodes();
+      void setESHeaderStartCodes(std::string newVal);
+      char getSLConfigDescriptorTypeTag();
+      void setSLConfigDescriptorTypeTag(char newVal);
+      uint32_t getSLConfigExtendedDescriptorTypeTag();//3 bytes
+      void setSLConfigExtendedDescriptorTypeTag(uint32_t newVal);//3 bytes
+      char getSLDescriptorTypeLength();
+      void setSLDescriptorTypeLength(char newVal);
+      char getSLValue();
+      void setSLValue(char newVal);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class FTYP: public Box{
+    public:
+      FTYP();
+      void setMajorBrand(uint32_t newMajorBrand);
+      uint32_t getMajorBrand();
+      void setMinorVersion(uint32_t newMinorVersion);
+      uint32_t getMinorVersion();
+      uint32_t getCompatibleBrandsCount();
+      void setCompatibleBrands(uint32_t newCompatibleBrand, size_t index);
+      uint32_t getCompatibleBrands(size_t index);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class MOOV: public containerBox{
+    public:
+      MOOV();
+  };
+  
+  class MVEX: public containerBox{
+    public:
+      MVEX();
+  };
+  
+  class TREX: public Box{
+    public:
+      TREX();
+      void setTrackID(uint32_t newTrackID);
+      uint32_t getTrackID();
+      void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
+      uint32_t getDefaultSampleDescriptionIndex();
+      void setDefaultSampleDuration(uint32_t newDefaultSampleDuration);
+      uint32_t getDefaultSampleDuration();
+      void setDefaultSampleSize(uint32_t newDefaultSampleSize);
+      uint32_t getDefaultSampleSize();
+      void setDefaultSampleFlags(uint32_t newDefaultSampleFlags);
+      uint32_t getDefaultSampleFlags();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  
+  class MFRA: public containerBox{
+    public:
+      MFRA();
+  };
+
+  class TRAK: public containerBox{
+    public:
+      TRAK();
+  };
+  
+  class MDIA: public containerBox{
+    public:
+      MDIA();
+  };
+
+  class MINF: public containerBox{
+    public:
+      MINF();
+  };
+
+  class DINF: public containerBox{
+    public:
+      DINF();
+  };
+
+  class MFRO: public Box{
+    public:
+      MFRO();
+      void setSize(uint32_t newSize);
+      uint32_t getSize();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class HDLR: public Box{
+    public:
+      HDLR();
+      void setSize(uint32_t newSize);
+      uint32_t getSize();
+      void setPreDefined(uint32_t newPreDefined);
+      uint32_t getPreDefined();
+      void setHandlerType(uint32_t newHandlerType);
+      uint32_t getHandlerType();
+      void setName(std::string newName);
+      std::string getName();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class VMHD: public fullBox{
+    public:
+      VMHD();
+      void setGraphicsMode(uint16_t newGraphicsMode);
+      uint16_t getGraphicsMode();
+      uint32_t getOpColorCount();
+      void setOpColor(uint16_t newOpColor, size_t index);
+      uint16_t getOpColor(size_t index);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class SMHD: public fullBox{
+    public:
+      SMHD();
+      void setBalance(int16_t newBalance);
+      int16_t getBalance();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class HMHD: public fullBox{
+    public:
+      HMHD();
+      void setMaxPDUSize(uint16_t newMaxPDUSize);
+      uint16_t getMaxPDUSize();
+      void setAvgPDUSize(uint16_t newAvgPDUSize);
+      uint16_t getAvgPDUSize();
+      void setMaxBitRate(uint32_t newMaxBitRate);
+      uint32_t getMaxBitRate();
+      void setAvgBitRate(uint32_t newAvgBitRate);
+      uint32_t getAvgBitRate();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class NMHD: public fullBox{
+    public:
+      NMHD();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class MEHD: public fullBox{
+    public:
+      MEHD();
+      void setFragmentDuration(uint64_t newFragmentDuration);
+      uint64_t getFragmentDuration();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class STBL: public containerBox{
+    public:
+      STBL();
+  };
+  
+  class URL: public fullBox{
+    public:
+      URL();
+      void setLocation(std::string newLocation);
+      std::string getLocation();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class URN: public fullBox{
+    public:
+      URN();
+      void setName(std::string newName);
+      std::string getName();
+      void setLocation(std::string newLocation);
+      std::string getLocation();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class DREF: public fullBox{
+    public:
+      DREF(char v = 1, uint32_t = 0);
+      uint32_t getEntryCount();
+      void setDataEntry(fullBox & newDataEntry, size_t index);
+      Box & getDataEntry(size_t index);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class MVHD: public fullBox{
+    public:
+      MVHD(char v = 1, uint32_t f = 0);
+      MVHD(long long unsigned int duration);
+      void setCreationTime(uint64_t newCreationTime);
+      uint64_t getCreationTime();
+      void setModificationTime(uint64_t newModificationTime);
+      uint64_t getModificationTime();
+      void setTimeScale(uint32_t newTimeScale);
+      uint32_t getTimeScale();
+      void setDuration(uint64_t newDuration);
+      uint64_t getDuration();
+      void setRate(uint32_t newRate);
+      uint32_t getRate();
+      void setVolume(uint16_t newVolume);
+      uint16_t getVolume();
+      ///\todo fix default values
+      uint32_t getMatrixCount();
+      void setMatrix(int32_t newMatrix, size_t index);
+      int32_t getMatrix(size_t index);
+      void setTrackID(uint32_t newTrackID);
+      uint32_t getTrackID();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  struct TFRAEntry{
+    uint64_t time;
+    uint64_t moofOffset;
+    uint32_t trafNumber;
+    uint32_t trunNumber;
+    uint32_t sampleNumber;
+  };
+  
+  class TFRA: public fullBox{
+    public:
+      TFRA();
+      void setTrackID(uint32_t newTrackID);
+      uint32_t getTrackID();
+      void setLengthSizeOfTrafNum(char newVal);
+      char getLengthSizeOfTrafNum();
+      void setLengthSizeOfTrunNum(char newVal);
+      char getLengthSizeOfTrunNum();
+      void setLengthSizeOfSampleNum(char newVal);
+      char getLengthSizeOfSampleNum();
+      void setNumberOfEntry(uint32_t newNumberOfEntry);
+      uint32_t getNumberOfEntry();
+      void setTFRAEntry(TFRAEntry newTFRAEntry, uint32_t no);
+      TFRAEntry & getTFRAEntry(uint32_t no);
+      uint32_t getTFRAEntrySize();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class TKHD: public fullBox{
+    public:
+      TKHD(char v = 1, uint32_t f = 0);
+      void setCreationTime(uint64_t newCreationTime);
+      uint64_t getCreationTime();
+      void setModificationTime(uint64_t newModificationTime);
+      uint64_t getModificationTime();
+      void setTrackID(uint32_t newTrackID);
+      uint32_t getTrackID();
+      void setDuration(uint64_t newDuration);
+      uint64_t getDuration();
+
+      void setLayer(uint16_t newLayer);
+      uint16_t getLayer();
+      void setAlternateGroup(uint16_t newAlternateGroup);
+      uint16_t getAlternateGroup();
+
+      void setVolume(uint16_t newVolume);
+      uint16_t getVolume();
+      ///\todo fix default values
+      uint32_t getMatrixCount();
+      void setMatrix(int32_t newMatrix, size_t index);
+      int32_t getMatrix(size_t index);
+
+      void setWidth(uint32_t newWidth);
+      uint32_t getWidth();
+      void setHeight(uint32_t newHeight);
+      uint32_t getHeight();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class MDHD: public fullBox{
+    public:
+      MDHD(char v = 1, uint32_t f = 0);
+      void setCreationTime(uint64_t newCreationTime);
+      uint64_t getCreationTime();
+      void setModificationTime(uint64_t newModificationTime);
+      uint64_t getModificationTime();
+      void setTimeScale(uint32_t newTimeScale);
+      uint32_t getTimeScale();
+      void setDuration(uint64_t newDuration);
+      uint64_t getDuration();
+      ///\todo return language properly
+      void setLanguage(uint16_t newLanguage);
+      uint16_t getLanguage();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  struct STTSEntry{
+    uint32_t sampleCount;
+    uint32_t sampleDelta;
+  };
+  
+  class STTS: public fullBox{
+    public:
+      STTS(char v = 1, uint32_t f = 0);
+      void setEntryCount(uint32_t newEntryCount);
+      uint32_t getEntryCount();
+      void setSTTSEntry(STTSEntry newSTTSEntry, uint32_t no);
+      STTSEntry getSTTSEntry(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  struct CTTSEntry{
+    uint32_t sampleCount;
+    uint32_t sampleOffset;
+  };
+
+  class CTTS: public fullBox{
+    public:
+      CTTS();
+      void setEntryCount(uint32_t newEntryCount);
+      uint32_t getEntryCount();
+      void setCTTSEntry(CTTSEntry newCTTSEntry, uint32_t no);
+      CTTSEntry getCTTSEntry(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  struct STSCEntry{
+    uint32_t firstChunk;
+    uint32_t samplesPerChunk;
+    uint32_t sampleDescriptionIndex;
+  };
+  
+  class STSC: public fullBox{
+    public:
+      STSC(char v = 1, uint32_t f = 0);
+      void setEntryCount(uint32_t newEntryCount);
+      uint32_t getEntryCount();
+      void setSTSCEntry(STSCEntry newSTSCEntry, uint32_t no);
+      STSCEntry getSTSCEntry(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class STCO: public fullBox{
+    public:
+      STCO(char v = 1, uint32_t f = 0);
+      void setEntryCount(uint32_t newEntryCount);
+      uint32_t getEntryCount();
+      void setChunkOffset(uint32_t newChunkOffset, uint32_t no);
+      uint32_t getChunkOffset(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class STSZ: public fullBox{
+    public:
+      STSZ(char v = 1, uint32_t f = 0);
+      void setSampleSize(uint32_t newSampleSize);
+      uint32_t getSampleSize();
+      void setSampleCount(uint32_t newSampleCount);
+      uint32_t getSampleCount();
+      void setEntrySize(uint32_t newEntrySize, uint32_t no);
+      uint32_t getEntrySize(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class SampleEntry: public Box{
+    public:
+      SampleEntry();
+      void setDataReferenceIndex(uint16_t newDataReferenceIndex);
+      uint16_t getDataReferenceIndex();
+      std::string toPrettySampleString(uint32_t index);
+  };
+  
+  class CLAP: public Box{//CleanApertureBox
+    public:
+      CLAP();
+      void setCleanApertureWidthN(uint32_t newVal);
+      uint32_t getCleanApertureWidthN();
+      void setCleanApertureWidthD(uint32_t newVal);
+      uint32_t getCleanApertureWidthD();
+      void setCleanApertureHeightN(uint32_t newVal);
+      uint32_t getCleanApertureHeightN();
+      void setCleanApertureHeightD(uint32_t newVal);
+      uint32_t getCleanApertureHeightD();
+      void setHorizOffN(uint32_t newVal);
+      uint32_t getHorizOffN();
+      void setHorizOffD(uint32_t newVal);
+      uint32_t getHorizOffD();
+      void setVertOffN(uint32_t newVal);
+      uint32_t getVertOffN();
+      void setVertOffD(uint32_t newVal);
+      uint32_t getVertOffD();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class PASP: public Box{ //PixelAspectRatioBox
+    public:
+      PASP();
+      void setHSpacing(uint32_t newVal);
+      uint32_t getHSpacing();
+      void setVSpacing(uint32_t newVal);
+      uint32_t getVSpacing();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class VisualSampleEntry: public SampleEntry{
+    ///\todo set default values
+    public:
+      VisualSampleEntry();
+      void setCodec(const char* newCodec);
+      void setWidth(uint16_t newWidth);
+      uint16_t getWidth();
+      void setHeight(uint16_t newHeight);
+      uint16_t getHeight();
+      void setHorizResolution (uint32_t newHorizResolution);
+      uint32_t getHorizResolution();
+      void setVertResolution (uint32_t newVertResolution);
+      uint32_t getVertResolution();
+      void setFrameCount(uint16_t newFrameCount);
+      uint16_t getFrameCount();
+      void setCompressorName(std::string newCompressorName);
+      std::string getCompressorName();
+      void setDepth(uint16_t newDepth);
+      uint16_t getDepth();
+      Box & getCLAP();
+      void setCLAP(Box& clap);
+      Box & getPASP();
+      std::string toPrettyVisualString(uint32_t index = 0, std::string = "");
+  };
+  
+  class AudioSampleEntry: public SampleEntry{
+    public:
+      ///\todo set default values
+      AudioSampleEntry();
+      void setCodec(const char* newCodec);
+      void setChannelCount(uint16_t newChannelCount);
+      uint16_t getChannelCount();
+      void setSampleSize(uint16_t newSampleSize);
+      uint16_t getSampleSize();
+      void setPreDefined(uint16_t newPreDefined);
+      uint16_t getPreDefined();
+      void setSampleRate(uint32_t newSampleRate);
+      uint32_t getSampleRate();
+      void setCodecBox(Box& newBox);
+      Box & getCodecBox();
+      std::string toPrettyAudioString(uint32_t indent = 0, std::string name = "");
+  };
+  
+  class MP4A: public AudioSampleEntry{
+    public:
+      MP4A();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class AAC: public AudioSampleEntry{
+    public:
+      AAC();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class AVC1: public VisualSampleEntry{
+    public:
+      AVC1();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class H264: public VisualSampleEntry{
+    public:
+      H264();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class STSD: public fullBox{
+    public:
+      STSD(char v = 1, uint32_t f = 0);
+      void setEntryCount (uint32_t newEntryCount);
+      uint32_t getEntryCount();
+      void setEntry(Box & newContent, uint32_t no);
+      Box & getEntry(uint32_t no);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class EDTS: public containerBox{
+    public:
+      EDTS();
+  };
+
+  class UDTA: public containerBox{
+    public:
+      UDTA();
+  };
+  
+  class STSS: public fullBox{
+    public:
+      STSS(char v = 1, uint32_t f = 0);
+      void setEntryCount(uint32_t newVal);
+      uint32_t getEntryCount();
+      void setSampleNumber(uint32_t newVal, uint32_t index);
+      uint32_t getSampleNumber(uint32_t index);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class META: public containerFullBox{
+    public:
+      META();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+  
+  class ELST: public fullBox{
+    public:
+      ELST();
+      void setSegmentDuration(uint64_t newVal);
+      uint64_t getSegmentDuration();
+      void setMediaTime(uint64_t newVal);
+      uint64_t getMediaTime();
+      void setMediaRateInteger(uint16_t newVal);
+      uint16_t getMediaRateInteger();
+      void setMediaRateFraction(uint16_t newVal);
+      uint16_t getMediaRateFraction();
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+}
diff --git a/lib/mp4_ms.cpp b/lib/mp4_ms.cpp
new file mode 100644
index 00000000..f96c346e
--- /dev/null
+++ b/lib/mp4_ms.cpp
@@ -0,0 +1,208 @@
+#include "mp4_ms.h"
+
+namespace MP4{
+
+  static char c2hex(int c){
+    if (c >= '0' && c <= '9') return c - '0';
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+    return 0;
+  }
+
+
+  SDTP::SDTP(){
+    memcpy(data + 4, "sdtp", 4);
+  }
+
+  void SDTP::setVersion(uint32_t newVersion){
+    setInt8(newVersion, 0);
+  }
+
+  uint32_t SDTP::getVersion(){
+    return getInt8(0);
+  }
+
+  void SDTP::setValue(uint32_t newValue, size_t index){
+    setInt8(newValue, index);
+  }
+
+  uint32_t SDTP::getValue(size_t index){
+    return getInt8(index);
+  }
+
+  std::string SDTP::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[sdtp] Sample Dependancy Type (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Samples: " << (boxedSize() - 12) << std::endl;
+    for (size_t i = 1; i <= boxedSize() - 12; ++i){
+      uint32_t val = getValue(i+3);
+      r << std::string(indent + 2, ' ') << "[" << i << "] = ";
+      switch (val & 3){
+        case 0:
+          r << "               ";
+          break;
+        case 1:
+          r << "Redundant,     ";
+          break;
+        case 2:
+          r << "Not redundant, ";
+          break;
+        case 3:
+          r << "Error,         ";
+          break;
+      }
+      switch (val & 12){
+        case 0:
+          r << "                ";
+          break;
+        case 4:
+          r << "Not disposable, ";
+          break;
+        case 8:
+          r << "Disposable,     ";
+          break;
+        case 12:
+          r << "Error,          ";
+          break;
+      }
+      switch (val & 48){
+        case 0:
+          r << "            ";
+          break;
+        case 16:
+          r << "IFrame,     ";
+          break;
+        case 32:
+          r << "Not IFrame, ";
+          break;
+        case 48:
+          r << "Error,      ";
+          break;
+      }
+      r << "(" << val << ")" << std::endl;
+    }
+    return r.str();
+  }
+
+  UUID::UUID(){
+    memcpy(data + 4, "uuid", 4);
+    setInt64(0, 0);
+    setInt64(0, 8);
+  }
+
+  std::string UUID::getUUID(){
+    std::stringstream r;
+    r << std::hex;
+    for (int i = 0; i < 16; ++i){
+      if (i == 4 || i == 6 || i == 8 || i == 10){
+        r << "-";
+      }
+      r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8+i]);
+    }
+    return r.str();
+  }
+
+  void UUID::setUUID(const std::string & uuid_string){
+    //reset UUID to zero
+    for (int i = 0; i < 4; ++i){
+      ((uint32_t*)(data+8))[i] = 0;
+    }
+    //set the UUID from the string, char by char
+    int i = 0;
+    for (size_t j = 0; j < uuid_string.size(); ++j){
+      if (uuid_string[j] == '-'){
+        continue;
+      }
+      data[8+i/2] |= (c2hex(uuid_string[j]) << ((~i & 1) << 2));
+      ++i;
+    }
+  }
+
+  void UUID::setUUID(const char * raw_uuid){
+    memcpy(data+8, raw_uuid, 16);
+  }
+
+  std::string UUID::toPrettyString(uint32_t indent){
+    std::string UUID = getUUID();
+    if (UUID == "d4807ef2-ca39-4695-8e54-26cb9e46a79f"){
+      return ((UUID_TrackFragmentReference*)this)->toPrettyString(indent);
+    }
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[uuid] Extension box (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "UUID: " << UUID << std::endl;
+    r << std::string(indent + 1, ' ') << "Unknown UUID - ignoring contents." << std::endl;
+    return r.str();
+  }
+
+  UUID_TrackFragmentReference::UUID_TrackFragmentReference(){
+    setUUID((std::string)"d4807ef2-ca39-4695-8e54-26cb9e46a79f");
+  }
+
+  void UUID_TrackFragmentReference::setVersion(uint32_t newVersion){
+    setInt8(newVersion, 16);
+  }
+  
+  uint32_t UUID_TrackFragmentReference::getVersion(){
+    return getInt8(16);
+  }
+  
+  void UUID_TrackFragmentReference::setFlags(uint32_t newFlags){
+    setInt24(newFlags, 17);
+  }
+  
+  uint32_t UUID_TrackFragmentReference::getFlags(){
+    return getInt24(17);
+  }
+  
+  void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount){
+    setInt8(newCount, 20);
+  }
+  
+  uint32_t UUID_TrackFragmentReference::getFragmentCount(){
+    return getInt8(20);
+  }
+  
+  void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime){
+    if (getVersion() == 0){
+      setInt32(newTime, 21+(num*8));
+    }else{
+      setInt64(newTime, 21+(num*16));
+    }
+  }
+  
+  uint64_t UUID_TrackFragmentReference::getTime(size_t num){
+    if (getVersion() == 0){
+      return getInt32(21+(num*8));
+    }else{
+      return getInt64(21+(num*16));
+    }
+  }
+  
+  void UUID_TrackFragmentReference::setDuration(size_t num, uint64_t newDuration){
+    if (getVersion() == 0){
+      setInt32(newDuration, 21+(num*8)+4);
+    }else{
+      setInt64(newDuration, 21+(num*16)+8);
+    }
+  }
+  
+  uint64_t UUID_TrackFragmentReference::getDuration(size_t num){
+    if (getVersion() == 0){
+      return getInt32(21+(num*8)+4);
+    }else{
+      return getInt64(21+(num*16)+8);
+    }
+  }
+
+  std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent){
+    std::stringstream r;
+    r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference (" << boxedSize() << ")" << std::endl;
+    r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl;
+    r << std::string(indent + 1, ' ') << "Fragments: " << getFragmentCount() << std::endl;
+    int j = getFragmentCount();
+    for (int i = 0; i < j; ++i){
+      r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i) << ", Duration = " << getDuration(i) << std::endl;
+    }
+    return r.str();
+  }
+}
diff --git a/lib/mp4_ms.h b/lib/mp4_ms.h
new file mode 100644
index 00000000..d9c809ae
--- /dev/null
+++ b/lib/mp4_ms.h
@@ -0,0 +1,40 @@
+#pragma once
+#include "mp4.h"
+
+namespace MP4{
+  class SDTP: public Box{
+    public:
+      SDTP();
+      void setVersion(uint32_t newVersion);
+      uint32_t getVersion();
+      void setValue(uint32_t newValue, size_t index);
+      uint32_t getValue(size_t index);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+        
+  class UUID: public Box{
+    public:
+      UUID();
+      std::string getUUID();
+      void setUUID(const std::string & uuid_string);
+      void setUUID(const char * raw_uuid);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+  class UUID_TrackFragmentReference: public UUID{
+    public:
+      UUID_TrackFragmentReference();
+      void setVersion(uint32_t newVersion);
+      uint32_t getVersion();
+      void setFlags(uint32_t newFlags);
+      uint32_t getFlags();
+      void setFragmentCount(uint32_t newCount);
+      uint32_t getFragmentCount();
+      void setTime(size_t num, uint64_t newTime);
+      uint64_t getTime(size_t num);
+      void setDuration(size_t num, uint64_t newDuration);
+      uint64_t getDuration(size_t num);
+      std::string toPrettyString(uint32_t indent = 0);
+  };
+
+}