diff --git a/lib/Makefile.am b/lib/Makefile.am
index 76d5de1c..d7a351a3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LIBRARIES=libamf.a libauth.a libbase64.a libconfig.a libcrypto.a libdtsc.a libflv_tag.a libhttp_parser.a libjson.a libmd5.a libprocs.a librtmpchunks.a libsocket.a libtinythread.a
+noinst_LIBRARIES=libamf.a libauth.a libbase64.a libconfig.a libcrypto.a libdtsc.a libflv_tag.a libhttp_parser.a libjson.a libmd5.a libprocs.a librtmpchunks.a libsocket.a libtinythread.a libmp4.a
 libamf_a_SOURCES=amf.h amf.cpp
 libauth_a_SOURCES=auth.h auth.cpp
 libbase64_a_SOURCES=base64.h base64.cpp
@@ -13,3 +13,4 @@ libprocs_a_SOURCES=procs.h procs.cpp
 librtmpchunks_a_SOURCES=rtmpchunks.h rtmpchunks.cpp
 libsocket_a_SOURCES=socket.h socket.cpp
 libtinythread_a_SOURCES=tinythread.h tinythread.cpp
+libmp4_a_SOURCES=mp4.h mp4.cpp
diff --git a/lib/mp4.cpp b/lib/mp4.cpp
new file mode 100644
index 00000000..ee0aa703
--- /dev/null
+++ b/lib/mp4.cpp
@@ -0,0 +1,413 @@
+#include "mp4.h"
+#include <stdlib.h> //for malloc and free
+#include <string.h> //for memcpy
+#include <arpa/inet.h> //for htonl and friends
+
+/// Contains all MP4 format related code.
+namespace MP4{
+
+Box::Box() {
+  Payload = (uint8_t *)malloc(8);
+  PayloadSize = 0;
+}
+
+Box::Box(uint32_t BoxType) {
+  Payload = (uint8_t *)malloc(8);
+  SetBoxType(BoxType);
+  PayloadSize = 0;
+}
+
+Box::Box(uint8_t * Content, uint32_t length) {
+  PayloadSize = length-8;
+  Payload = (uint8_t *)malloc(length);
+  memcpy(Payload, Content, length);
+}
+
+Box::~Box() {
+  if (Payload) free(Payload);
+}
+
+void Box::SetBoxType(uint32_t BoxType) {
+  ((unsigned int*)Payload)[1] = htonl(BoxType);
+}
+
+uint32_t Box::GetBoxType() {
+  return ntohl(((unsigned int*)Payload)[1]);
+}
+
+void Box::SetPayload(uint32_t Size, uint8_t * Data, uint32_t Index) {
+  if ( Index + Size > PayloadSize ) {
+    PayloadSize = Index + Size;
+    ((unsigned int*)Payload)[0] = htonl(PayloadSize+8);
+    Payload = (uint8_t *)realloc(Payload, PayloadSize + 8);
+  }
+  memcpy(Payload + 8 + Index, Data, Size);
+}
+
+uint32_t Box::GetPayloadSize() {
+  return PayloadSize;
+}
+
+uint8_t * Box::GetPayload() {
+  return Payload+8;
+}
+
+uint8_t * Box::GetPayload(uint32_t Index, uint32_t & Size) {
+  if(Index > PayloadSize) {Size = 0;}
+  if(Index + Size > PayloadSize) { Size = PayloadSize - Index; }
+  return Payload + 8 + Index;
+}
+
+uint32_t Box::GetBoxedDataSize() {
+  return ntohl(((unsigned int*)Payload)[0]);
+}
+
+uint8_t * Box::GetBoxedData( ) {
+  return Payload;
+}
+
+
+uint8_t * Box::uint32_to_uint8( uint32_t data ) {
+  uint8_t * temp = new uint8_t[4];
+  temp[0] = (data >> 24) & 0x000000FF;
+  temp[1] = (data >> 16 ) & 0x000000FF;
+  temp[2] = (data >> 8 ) & 0x000000FF;
+  temp[3] = (data ) & 0x000000FF;
+  return temp;
+}
+
+uint8_t * Box::uint16_to_uint8( uint16_t data ) {
+  uint8_t * temp = new uint8_t[2];
+  temp[0] = (data >> 8) & 0x00FF;
+  temp[1] = (data  ) & 0x00FF;
+  return temp;
+}
+
+uint8_t * Box::uint8_to_uint8( uint8_t data ) {
+  uint8_t * temp = new uint8_t[1];
+  temp[0] = data;
+  return temp;
+}
+
+void Box::ResetPayload( ) {
+  PayloadSize = 0;
+  Payload = (uint8_t *)realloc(Payload, PayloadSize + 8);
+  ((unsigned int*)Payload)[0] = htonl(0);
+}
+
+void ABST::SetBootstrapVersion( uint32_t Version ) {
+  curBootstrapInfoVersion = Version;
+}
+
+void ABST::SetProfile( uint8_t Profile ) {
+  curProfile = Profile;
+}
+
+void ABST::SetLive( bool Live ) {
+  isLive = Live;
+}
+
+void ABST::SetUpdate( bool Update ) {
+  isUpdate = Update;
+}
+
+void ABST::SetTimeScale( uint32_t Scale ) {
+  curTimeScale = Scale;
+}
+
+void ABST::SetMediaTime( uint32_t Time ) {
+  curMediatime = Time;
+}
+
+void ABST::SetSMPTE( uint32_t Smpte ) {
+  curSMPTE = Smpte;
+}
+
+void ABST::SetMovieIdentifier( std::string Identifier ) {
+  curMovieIdentifier = Identifier;
+}
+
+void ABST::SetDRM( std::string Drm ) {
+  curDRM = Drm;
+}
+
+void ABST::SetMetaData( std::string MetaData ) {
+  curMetaData = MetaData;
+}
+
+void ABST::AddServerEntry( std::string Url, uint32_t Offset ) {
+  if(Offset >= Servers.size()) {
+    Servers.resize(Offset+1);
+  }
+  Servers[Offset].ServerBaseUrl = Url;
+}
+
+void ABST::AddQualityEntry( std::string Quality, uint32_t Offset ) {
+  if(Offset >= Qualities.size()) {
+    Qualities.resize(Offset+1);
+  }
+  Qualities[Offset].QualityModifier = Quality;
+}
+
+void ABST::AddSegmentRunTable( Box * newSegment, uint32_t Offset ) {
+  if( Offset >= SegmentRunTables.size() ) {
+    SegmentRunTables.resize(Offset+1);
+  }
+  if( SegmentRunTables[Offset] ) {
+    delete SegmentRunTables[Offset];
+  }
+  SegmentRunTables[Offset] = newSegment;
+}
+
+void ABST::AddFragmentRunTable( Box * newFragment, uint32_t Offset ) {
+  if( Offset >= FragmentRunTables.size() ) {
+    FragmentRunTables.resize(Offset+1);
+  }
+  if( FragmentRunTables[Offset] ) {
+    delete FragmentRunTables[Offset];
+  }
+  FragmentRunTables[Offset] = newFragment;
+}
+
+void ABST::SetDefaults( ) {
+  SetProfile( );
+  SetLive( );
+  SetUpdate( );
+  SetTimeScale( );
+  SetMediaTime( );
+  SetSMPTE( );
+  SetMovieIdentifier( );
+  SetDRM( );
+  SetMetaData( );
+  SetVersion( );
+}
+
+void ABST::SetVersion( bool NewVersion) {
+  Version = NewVersion;
+}
+
+void ABST::SetReserved( ) {
+  Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
+}
+
+void ABST::WriteContent( ) {
+  Box * current;
+  std::string serializedServers = "";
+  std::string serializedQualities = "";
+  std::string serializedSegments = "";
+  std::string serializedFragments = "";
+  int SegmentAmount = 0;
+  int FragmentAmount = 0;
+  uint8_t * temp = new uint8_t[1];
+  
+  ResetPayload( );
+  SetReserved( );
+  
+  for( uint32_t i = 0; i < Servers.size(); i++ ) {
+    serializedServers.append(Servers[i].ServerBaseUrl.c_str());
+    serializedServers += '\0';
+  }
+  for( uint32_t i = 0; i < Qualities.size(); i++ ) {
+    serializedQualities.append(Qualities[i].QualityModifier.c_str());
+    serializedQualities += '\0';
+  }
+  for( uint32_t i = 0; i < SegmentRunTables.size(); i++ ) {
+    current=SegmentRunTables[i];
+    if( current ) {
+      SegmentAmount ++;
+      serializedSegments.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
+    }
+  }
+  for( uint32_t i = 0; i < FragmentRunTables.size(); i++ ) {
+    current=FragmentRunTables[i];
+    if( current ) {
+      FragmentAmount ++;
+      serializedFragments.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
+    }
+  }
+  uint32_t OffsetServerEntryCount = 29 + curMovieIdentifier.size() + 1;
+  uint32_t OffsetQualityEntryCount = OffsetServerEntryCount + 1 + serializedServers.size();
+  uint32_t OffsetDrmData = OffsetQualityEntryCount + 1 + serializedQualities.size();
+  uint32_t OffsetMetaData = OffsetDrmData + curDRM.size() + 1;
+  uint32_t OffsetSegmentRuntableCount = OffsetMetaData + curMetaData.size() + 1;
+  uint32_t OffsetFragmentRuntableCount = OffsetSegmentRuntableCount + 1 + serializedSegments.size();
+  
+  temp[0] = 0 + ( curProfile << 6 ) + ( (uint8_t)isLive << 7 ) + ( (uint8_t)isUpdate << 7 );
+  
+  SetPayload((uint32_t)serializedFragments.size(),(uint8_t*)serializedFragments.c_str(),OffsetFragmentRuntableCount+1);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(FragmentAmount),OffsetFragmentRuntableCount);
+  SetPayload((uint32_t)serializedSegments.size(),(uint8_t*)serializedSegments.c_str(),OffsetSegmentRuntableCount+1);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(SegmentAmount),OffsetSegmentRuntableCount);
+  SetPayload((uint32_t)curMetaData.size()+1,(uint8_t*)curMetaData.c_str(),OffsetMetaData);
+  SetPayload((uint32_t)curDRM.size()+1,(uint8_t*)curDRM.c_str(),OffsetDrmData);
+  SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),OffsetQualityEntryCount+1);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(Qualities.size()),OffsetQualityEntryCount);
+  SetPayload((uint32_t)serializedServers.size(),(uint8_t*)serializedServers.c_str(),OffsetServerEntryCount+1);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(Servers.size()),OffsetServerEntryCount);
+  SetPayload((uint32_t)curMovieIdentifier.size()+1,(uint8_t*)curMovieIdentifier.c_str(),29);//+1 for \0-terminated string...
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(curSMPTE),25);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(0),21);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(curMediatime),17);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(0),13);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(curTimeScale),9);
+  SetPayload((uint32_t)1,temp,8);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(curBootstrapInfoVersion),4);
+}
+
+void AFRT::SetUpdate( bool Update ) {
+  isUpdate = Update;
+}
+
+void AFRT::AddQualityEntry( std::string Quality, uint32_t Offset ) {
+  if(Offset >= QualitySegmentUrlModifiers.size()) {
+    QualitySegmentUrlModifiers.resize(Offset+1);
+  }
+  QualitySegmentUrlModifiers[Offset] = Quality;
+}
+
+void AFRT::AddFragmentRunEntry( uint32_t FirstFragment, uint32_t FirstFragmentTimestamp, uint32_t FragmentsDuration, uint8_t Discontinuity, uint32_t Offset ) {
+  if( Offset >= FragmentRunEntryTable.size() ) {
+    FragmentRunEntryTable.resize(Offset+1);
+  }
+  FragmentRunEntryTable[Offset].FirstFragment = FirstFragment;
+  FragmentRunEntryTable[Offset].FirstFragmentTimestamp = FirstFragmentTimestamp;
+  FragmentRunEntryTable[Offset].FragmentDuration = FragmentsDuration;
+  if( FragmentsDuration == 0) {
+    FragmentRunEntryTable[Offset].DiscontinuityIndicator = Discontinuity;
+  }
+}
+
+void AFRT::SetDefaults( ) {
+  SetUpdate( );
+  SetTimeScale( );
+}
+
+void AFRT::SetTimeScale( uint32_t Scale ) {
+  curTimeScale = Scale;
+}
+
+void AFRT::WriteContent( ) {
+  std::string serializedQualities = "";
+  std::string serializedFragmentEntries = "";
+  ResetPayload( );
+  
+  for( uint32_t i = 0; i < QualitySegmentUrlModifiers.size(); i++ ) {
+    serializedQualities.append(QualitySegmentUrlModifiers[i].c_str());
+    serializedQualities += '\0';
+  }
+  for( uint32_t i = 0; i < FragmentRunEntryTable.size(); i ++ ) {
+    serializedFragmentEntries.append((char*)Box::uint32_to_uint8(FragmentRunEntryTable[i].FirstFragment),4);
+    serializedFragmentEntries.append((char*)Box::uint32_to_uint8(0),4);
+    serializedFragmentEntries.append((char*)Box::uint32_to_uint8(FragmentRunEntryTable[i].FirstFragmentTimestamp),4);
+    serializedFragmentEntries.append((char*)Box::uint32_to_uint8(FragmentRunEntryTable[i].FragmentDuration),4);
+    if(FragmentRunEntryTable[i].FragmentDuration == 0) {
+      serializedFragmentEntries.append((char*)Box::uint8_to_uint8(FragmentRunEntryTable[i].DiscontinuityIndicator),1);
+    }
+  }
+  
+  uint32_t OffsetFragmentRunEntryCount = 9 + serializedQualities.size();
+  
+  SetPayload((uint32_t)serializedFragmentEntries.size(),(uint8_t*)serializedFragmentEntries.c_str(),OffsetFragmentRunEntryCount+4);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(FragmentRunEntryTable.size()),OffsetFragmentRunEntryCount);
+  SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),9);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(QualitySegmentUrlModifiers.size()),8);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(curTimeScale),4);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8((isUpdate ? 1 : 0)));
+}
+
+void ASRT::SetUpdate( bool Update ) {
+  isUpdate = Update;
+}
+
+void ASRT::AddQualityEntry( std::string Quality, uint32_t Offset ) {
+  if(Offset >= QualitySegmentUrlModifiers.size()) {
+    QualitySegmentUrlModifiers.resize(Offset+1);
+  }
+  QualitySegmentUrlModifiers[Offset] = Quality;
+}
+
+void ASRT::AddSegmentRunEntry( uint32_t FirstSegment, uint32_t FragmentsPerSegment, uint32_t Offset ) {
+  if( Offset >= SegmentRunEntryTable.size() ) {
+    SegmentRunEntryTable.resize(Offset+1);
+  }
+  SegmentRunEntryTable[Offset].FirstSegment = FirstSegment;
+  SegmentRunEntryTable[Offset].FragmentsPerSegment = FragmentsPerSegment;
+}
+
+void ASRT::SetVersion( bool NewVersion ) {
+  Version = NewVersion;
+}
+
+void ASRT::SetDefaults( ) {
+  SetUpdate( );
+}
+
+void ASRT::WriteContent( ) {
+  std::string serializedQualities = "";
+  ResetPayload( );
+  
+  for( uint32_t i = 0; i < QualitySegmentUrlModifiers.size(); i++ ) {
+    serializedQualities.append(QualitySegmentUrlModifiers[i].c_str());
+    serializedQualities += '\0';
+  }
+  
+  uint32_t OffsetSegmentRunEntryCount = 5 + serializedQualities.size();
+  
+  for( uint32_t i = 0; i < SegmentRunEntryTable.size(); i ++ ) {
+    SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable[i].FragmentsPerSegment),(8*i)+OffsetSegmentRunEntryCount+8);
+    SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable[i].FirstSegment),(8*i)+OffsetSegmentRunEntryCount+4);
+  }
+  SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable.size()),OffsetSegmentRunEntryCount);
+  SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),5);
+  SetPayload((uint32_t)1,Box::uint8_to_uint8(QualitySegmentUrlModifiers.size()),4);
+  SetPayload((uint32_t)4,Box::uint32_to_uint8((isUpdate ? 1 : 0)));
+}
+
+std::string GenerateLiveBootstrap( uint32_t CurMediaTime ) {
+  AFRT afrt;
+  afrt.SetUpdate(false);
+  afrt.SetTimeScale(1000);
+  afrt.AddQualityEntry("");
+  afrt.AddFragmentRunEntry(1, 0 , 4000); //FirstFragment, FirstFragmentTimestamp,Fragment Duration in milliseconds
+  afrt.WriteContent();
+
+  ASRT asrt;
+  asrt.SetUpdate(false);
+  asrt.AddQualityEntry("");
+  asrt.AddSegmentRunEntry(1, 199);//1 Segment, 199 Fragments
+  asrt.WriteContent();
+
+  ABST abst;
+  abst.AddFragmentRunTable(&afrt);
+  abst.AddSegmentRunTable(&asrt);
+  abst.SetBootstrapVersion(1);
+  abst.SetProfile(0);
+  abst.SetLive(true);
+  abst.SetUpdate(false);
+  abst.SetTimeScale(1000);
+  abst.SetMediaTime(0xFFFFFFFF);
+  abst.SetSMPTE(0);
+  abst.SetMovieIdentifier("fifa");
+  abst.SetDRM("");
+  abst.SetMetaData("");
+  abst.AddServerEntry("");
+  abst.AddQualityEntry("");
+  abst.WriteContent();
+
+  std::string Result;
+  Result.append((char*)abst.GetBoxedData(), (int)abst.GetBoxedDataSize());
+  return Result;
+}
+
+std::string mdatFold(std::string data){
+  std::string Result;
+  unsigned int t_int;
+  t_int = htonl(data.size()+8);
+  Result.append((char*)&t_int, 4);
+  t_int = htonl(0x6D646174);
+  Result.append((char*)&t_int, 4);
+  Result.append(data);
+  return Result;
+}
+
+};
diff --git a/lib/mp4.h b/lib/mp4.h
new file mode 100644
index 00000000..b4ec5417
--- /dev/null
+++ b/lib/mp4.h
@@ -0,0 +1,132 @@
+#pragma once
+#include <string>
+#include <stdint.h>
+#include <vector>
+
+/// Contains all MP4 format related code.
+namespace MP4{
+
+  class Box {
+    public:
+      Box();
+      Box(uint32_t BoxType);
+      Box(uint8_t * Content, uint32_t length);
+      ~Box();
+      void SetBoxType(uint32_t BoxType);
+      uint32_t GetBoxType();
+      void SetPayload(uint32_t Size, uint8_t * Data, uint32_t Index = 0);
+      uint32_t GetPayloadSize();
+      uint8_t * GetPayload();
+      uint8_t * GetPayload(uint32_t Index, uint32_t & Size);
+      uint32_t GetBoxedDataSize();
+      uint8_t * GetBoxedData( );
+      static uint8_t * uint32_to_uint8( uint32_t data );
+      static uint8_t * uint16_to_uint8( uint16_t data );
+      static uint8_t * uint8_to_uint8( uint8_t data );
+      void ResetPayload( );
+    private:
+      uint8_t * Payload;
+      uint32_t PayloadSize;
+  };//Box Class
+
+  struct abst_serverentry {
+    std::string ServerBaseUrl;
+  };//abst_serverentry
+
+  struct abst_qualityentry {
+    std::string QualityModifier;
+  };//abst_qualityentry
+
+  /// ABST Box class
+  class ABST: public Box {
+    public:
+      ABST() : Box(0x61627374){};
+      void SetBootstrapVersion( uint32_t Version = 1 );
+      void SetProfile( uint8_t Profile = 0 );
+      void SetLive( bool Live = true );
+      void SetUpdate( bool Update = false );
+      void SetTimeScale( uint32_t Scale = 1000 );
+      void SetMediaTime( uint32_t Time = 0 );
+      void SetSMPTE( uint32_t Smpte = 0 );
+      void SetMovieIdentifier( std::string Identifier = "" );
+      void SetDRM( std::string Drm = "" );
+      void SetMetaData( std::string MetaData = "" );
+      void AddServerEntry( std::string Url = "", uint32_t Offset = 0 );
+      void AddQualityEntry( std::string Quality = "", uint32_t Offset = 0 );
+      void AddSegmentRunTable( Box * newSegment, uint32_t Offset = 0 );
+      void AddFragmentRunTable( Box * newFragment, uint32_t Offset = 0 );
+      void SetVersion( bool NewVersion = 0 );
+      void WriteContent( );
+    private:
+      void SetDefaults( );
+      void SetReserved( );
+      uint32_t curBootstrapInfoVersion;
+      uint8_t curProfile;
+      bool isLive;
+      bool isUpdate;
+      bool Version;
+      uint32_t curTimeScale;
+      uint32_t curMediatime;//write as uint64_t
+      uint32_t curSMPTE;//write as uint64_t
+      std::string curMovieIdentifier;
+      std::string curDRM;
+      std::string curMetaData;
+      std::vector<abst_serverentry> Servers;
+      std::vector<abst_qualityentry> Qualities;
+      std::vector<Box *> SegmentRunTables;
+      std::vector<Box *> FragmentRunTables;
+      Box * Container;
+  };//ABST Box
+
+  struct afrt_fragmentrunentry {
+    uint32_t FirstFragment;
+    uint32_t FirstFragmentTimestamp; //write as uint64_t
+    uint32_t FragmentDuration;
+    uint8_t DiscontinuityIndicator;//if FragmentDuration == 0
+  };//afrt_fragmentrunentry
+
+
+  /// AFRT Box class
+  class AFRT : public Box {
+    public:
+      AFRT() : Box(0x61667274){};
+      void SetUpdate( bool Update = false );
+      void SetTimeScale( uint32_t Scale = 1000 );
+      void AddQualityEntry( std::string Quality = "", uint32_t Offset = 0 );
+      void AddFragmentRunEntry( uint32_t FirstFragment = 0, uint32_t FirstFragmentTimestamp = 0, uint32_t FragmentsDuration = 1, uint8_t Discontinuity = 0, uint32_t Offset = 0 );
+      void WriteContent( );
+    private:
+      void SetDefaults( );
+      bool isUpdate;
+      uint32_t curTimeScale;
+      std::vector<std::string> QualitySegmentUrlModifiers;
+      std::vector<afrt_fragmentrunentry> FragmentRunEntryTable;
+  };//AFRT Box
+
+  struct asrt_segmentrunentry {
+    uint32_t FirstSegment;
+    uint32_t FragmentsPerSegment;
+  };//abst_qualityentry
+
+  /// ASRT Box class
+  class ASRT : public Box {
+    public:
+      ASRT() : Box(0x61737274){};
+      void SetUpdate( bool Update = false );
+      void AddQualityEntry( std::string Quality = "", uint32_t Offset = 0 );
+      void AddSegmentRunEntry( uint32_t FirstSegment = 0, uint32_t FragmentsPerSegment = 100, uint32_t Offset = 0 );
+      void WriteContent( );
+      void SetVersion( bool NewVersion = 0 );
+    private:
+      void SetDefaults( );
+      bool isUpdate;
+      bool Version;
+      std::vector<std::string> QualitySegmentUrlModifiers;
+      std::vector<asrt_segmentrunentry> SegmentRunEntryTable;
+      Box * Container;
+  };//ASRT Box
+
+  std::string GenerateLiveBootstrap( uint32_t CurMediaTime );
+  std::string mdatFold(std::string data);
+
+};
diff --git a/src/Makefile.am b/src/Makefile.am
index dd0322b2..a8ad7a82 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,4 +10,4 @@ MistConnRAW_LDADD=-lsocket
 MistConnRTMP_SOURCES=conn_rtmp.cpp
 MistConnRTMP_LDADD=-lsocket -ldtsc -lrtmpchunks -lflv_tag -lconfig -lamf -lssl -lcrypto
 MistConnHTTP_SOURCES=conn_http.cpp
-MistConnHTTP_LDADD=-lsocket
+MistConnHTTP_LDADD=-lsocket -ldtsc -lflv_tag -lamf -ljson -lhttp_parser -lmp4 -lprocs -lbase64 -lconfig
diff --git a/src/conn_http.cpp b/src/conn_http.cpp
index 090f0901..4e5d0cd6 100644
--- a/src/conn_http.cpp
+++ b/src/conn_http.cpp
@@ -18,6 +18,7 @@
 #include "../lib/flv_tag.h"
 #include "../lib/base64.h"
 #include "../lib/amf.h"
+#include "../lib/mp4.h"
 
 /// Holds everything unique to HTTP Connector.
 namespace Connector_HTTP{
@@ -29,18 +30,6 @@ namespace Connector_HTTP{
   DTSC::Stream Strm;///< Incoming stream buffer.
   HTTP::Parser HTTP_R, HTTP_S;///<HTTP Receiver en HTTP Sender.
 
-  /// Folds data into a mdat container and returns it.
-  std::string mdatFold(std::string data){
-    std::string Result;
-    unsigned int t_int;
-    t_int = htonl(data.size()+8);
-    Result.append((char*)&t_int, 4);
-    t_int = htonl(0x6D646174);
-    Result.append((char*)&t_int, 4);
-    Result.append(data);
-    return Result;
-  }
-
   /// Returns AMF-format metadata for Adobe HTTP Dynamic Streaming.
   std::string GetMetaData( ) {
     AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
@@ -82,7 +71,6 @@ namespace Connector_HTTP{
 
   /// Returns a F4M-format manifest file for Adobe HTTP Dynamic Streaming.
   std::string BuildManifest(std::string MovieId) {
-    Interface * temp = new Interface;
     std::string Result="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n";
     Result += "<id>";
     Result += MovieId;
@@ -90,7 +78,7 @@ namespace Connector_HTTP{
     Result += "<streamType>live</streamType>\n";
     Result += "<deliveryType>streaming</deliveryType>\n";
     Result += "<bootstrapInfo profile=\"named\" id=\"bootstrap1\">";
-    Result += Base64::encode(temp->GenerateLiveBootstrap(1));
+    Result += Base64::encode(MP4::GenerateLiveBootstrap(1));
     Result += "</bootstrapInfo>\n";
     Result += "<media streamId=\"1\" bootstrapInfoId=\"bootstrap1\" url=\"";
     Result += MovieId;
@@ -100,7 +88,6 @@ namespace Connector_HTTP{
     Result += "</metadata>\n";
     Result += "</media>\n";
     Result += "</manifest>\n";
-    delete temp;
     return Result;
   }//BuildManifest
 
@@ -279,7 +266,7 @@ namespace Connector_HTTP{
         if ((Flash_RequestPending > 0) && !Flash_FragBuffer.empty()){
           HTTP_S.Clean();
           HTTP_S.SetHeader("Content-Type","video/mp4");
-          HTTP_S.SetBody(mdatFold(Flash_FragBuffer.front()));
+          HTTP_S.SetBody(MP4::mdatFold(Flash_FragBuffer.front()));
           Flash_FragBuffer.pop();
           HTTP_S.SendResponse(conn, "200", "OK");//schrijf de HTTP response header
           Flash_RequestPending--;