Bijna klaar!

This commit is contained in:
Thulinma 2011-02-16 21:42:40 +01:00
parent a30f63ab5a
commit 183827ae9f
42 changed files with 3198 additions and 0 deletions

18
util/MP4/Makefile Normal file
View file

@ -0,0 +1,18 @@
SRC = box_abst.cpp box_afra.cpp box_afrt.cpp box_amhp.cpp box_asrt.cpp box_avcC.cpp box.cpp box_dinf.cpp box_dref.cpp box_esds.cpp box_ftyp.cpp box_hdlr.cpp box_hmhd.cpp box_mdat.cpp box_mdhd.cpp box_mdia.cpp box_mfhd.cpp box_minf.cpp box_moof.cpp box_moov.cpp box_mvex.cpp box_mvhd.cpp box_nmhd.cpp box_rtmp.cpp box_smhd.cpp box_stbl.cpp box_stco.cpp box_stsc.cpp box_stsd.cpp box_stts.cpp box_tfhd.cpp box_tkhd.cpp box_traf.cpp box_trak.cpp box_trex.cpp box_trun.cpp box_url.cpp box_vmhd.cpp interface.cpp main.cpp
OBJ = $(SRC:.cpp=.o)
OUT = Boxtest
INCLUDES =
CCFLAGS = -Wall -Wextra -funsigned-char -g
CC = $(CROSS)g++
LD = $(CROSS)ld
AR = $(CROSS)ar
LIBS =
.SUFFIXES: .cpp
.PHONY: clean default
default: $(OUT)
.cpp.o:
$(CC) $(INCLUDES) $(CCFLAGS) $(LIBS) -c $< -o $@
$(OUT): $(OBJ)
$(CC) $(LIBS) -o $(OUT) $(OBJ)
clean:
rm -rf $(OBJ) $(OUT) Makefile.bak *~

150
util/MP4/box.cpp Normal file
View file

@ -0,0 +1,150 @@
#pragma once
#include <stdint.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
struct BoxHeader {
uint32_t TotalSize;
uint32_t BoxType;
};//BoxHeader struct
class Box {
public:
Box();
Box(uint32_t BoxType);
~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 );
BoxHeader GetHeader( );
void ResetPayload( );
private:
BoxHeader header;
uint8_t * Payload;
uint32_t PayloadSize;
};//Box Class
Box::Box() {
Payload = NULL;
PayloadSize = 0;
}
Box::Box(uint32_t BoxType) {
header.BoxType = BoxType;
Payload = NULL;
PayloadSize = 0;
}
Box::~Box() {
}
void Box::SetBoxType(uint32_t BoxType) {
header.BoxType = BoxType;
}
uint32_t Box::GetBoxType() {
return header.BoxType;
}
void Box::SetPayload(uint32_t Size, uint8_t * Data, uint32_t Index) {
uint8_t * tempchar = NULL;
if ( Index + Size > PayloadSize ) {
if ( Payload ) {
tempchar = new uint8_t[PayloadSize];
memcpy( tempchar, Payload, PayloadSize );
delete Payload;
}
PayloadSize = Index + Size;
Payload = new uint8_t[PayloadSize];
if( tempchar ) {
memcpy( Payload, tempchar, Index );
} else {
for(uint32_t i = 0; i < Index; i++) { Payload[i] = 0; }
}
memcpy( &Payload[Index], Data, Size );
header.TotalSize = PayloadSize + 8;
if( tempchar ) {
delete tempchar;
}
} else {
memcpy( &Payload[Index], Data, Size );
}
}
uint32_t Box::GetPayloadSize() {
return PayloadSize;
}
uint8_t * Box::GetPayload() {
uint8_t * temp = new uint8_t[PayloadSize];
memcpy( temp, Payload, PayloadSize );
return temp;
}
uint8_t * Box::GetPayload(uint32_t Index, uint32_t & Size) {
if(Index > PayloadSize) { return NULL; }
if(Index + Size > PayloadSize) { Size = PayloadSize - Index; }
uint8_t * temp = new uint8_t[Size - Index];
memcpy( temp, &Payload[Index], Size - Index );
return temp;
}
uint32_t Box::GetBoxedDataSize() {
return header.TotalSize;
}
uint8_t * Box::GetBoxedData( ) {
uint8_t * temp = new uint8_t[header.TotalSize];
memcpy( temp, uint32_to_uint8(header.TotalSize), 4 );
memcpy( &temp[4], uint32_to_uint8(header.BoxType), 4 );
memcpy( &temp[8], Payload, PayloadSize );
return temp;
}
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;
}
BoxHeader Box::GetHeader( ) {
return header;
}
void Box::ResetPayload( ) {
header.TotalSize -= PayloadSize;
PayloadSize = 0;
if(Payload) {
delete Payload;
Payload = NULL;
}
}

218
util/MP4/box_abst.cpp Normal file
View file

@ -0,0 +1,218 @@
#include "box.cpp"
#include <string>
#include <vector>
struct abst_serverentry {
std::string ServerBaseUrl;
};//abst_serverentry
struct abst_qualityentry {
std::string QualityModifier;
};//abst_qualityentry
class Box_abst {
public:
Box_abst( );
~Box_abst();
Box * GetBox();
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 WriteContent( );
private:
void SetDefaults( );
void SetReserved( );
uint32_t curBootstrapInfoVersion;
uint8_t curProfile;
bool isLive;
bool isUpdate;
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;
};//Box_ftyp Class
Box_abst::Box_abst( ) {
Container = new Box( 0x61627374 );
}
Box_abst::~Box_abst() {
delete Container;
}
Box * Box_abst::GetBox() {
return Container;
}
void Box_abst::SetBootstrapVersion( uint32_t Version ) {
curBootstrapInfoVersion = Version;
}
void Box_abst::SetProfile( uint8_t Profile ) {
curProfile = Profile;
}
void Box_abst::SetLive( bool Live ) {
isLive = Live;
}
void Box_abst::SetUpdate( bool Update ) {
isUpdate = Update;
}
void Box_abst::SetTimeScale( uint32_t Scale ) {
curTimeScale = Scale;
}
void Box_abst::SetMediaTime( uint32_t Time ) {
curMediatime = Time;
}
void Box_abst::SetSMPTE( uint32_t Smpte ) {
curSMPTE = Smpte;
}
void Box_abst::SetMovieIdentifier( std::string Identifier ) {
curMovieIdentifier = Identifier;
}
void Box_abst::SetDRM( std::string Drm ) {
curDRM = Drm;
}
void Box_abst::SetMetaData( std::string MetaData ) {
curMetaData = MetaData;
}
void Box_abst::AddServerEntry( std::string Url, uint32_t Offset ) {
if(Offset >= Servers.size()) {
Servers.resize(Offset+1);
}
Servers[Offset].ServerBaseUrl = Url;
}
void Box_abst::AddQualityEntry( std::string Quality, uint32_t Offset ) {
if(Offset >= Qualities.size()) {
Qualities.resize(Offset+1);
}
Qualities[Offset].QualityModifier = Quality;
}
void Box_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 Box_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 Box_abst::SetDefaults( ) {
SetProfile( );
SetLive( );
SetUpdate( );
SetTimeScale( );
SetMediaTime( );
SetSMPTE( );
SetMovieIdentifier( );
SetDRM( );
SetMetaData( );
}
void Box_abst::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_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];
Container->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 + 4 + serializedServers.size();
uint32_t OffsetDrmData = OffsetQualityEntryCount + 4 + serializedQualities.size();
uint32_t OffsetMetaData = OffsetDrmData + curDRM.size() + 1;
uint32_t OffsetSegmentRuntableCount = OffsetMetaData + curMetaData.size() + 1;
uint32_t OffsetFragmentRuntableCount = OffsetSegmentRuntableCount + 4 + serializedSegments.size();
temp[0] = 0 & ( curProfile << 6 ) & ( (uint8_t)isLive << 7 ) & ( (uint8_t)isUpdate << 7 );
Container->SetPayload((uint32_t)serializedFragments.size(),(uint8_t*)serializedFragments.c_str(),OffsetFragmentRuntableCount+4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(FragmentAmount),OffsetFragmentRuntableCount);
Container->SetPayload((uint32_t)serializedSegments.size(),(uint8_t*)serializedSegments.c_str(),OffsetSegmentRuntableCount+4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentAmount),OffsetSegmentRuntableCount);
Container->SetPayload((uint32_t)curMetaData.size()+1,(uint8_t*)curMetaData.c_str(),OffsetMetaData);
Container->SetPayload((uint32_t)curDRM.size()+1,(uint8_t*)curDRM.c_str(),OffsetDrmData);
Container->SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),OffsetQualityEntryCount+4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Qualities.size()),OffsetQualityEntryCount);
Container->SetPayload((uint32_t)serializedServers.size(),(uint8_t*)serializedServers.c_str(),OffsetServerEntryCount+4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Servers.size()),OffsetServerEntryCount);
Container->SetPayload((uint32_t)curMovieIdentifier.size()+1,(uint8_t*)curMovieIdentifier.c_str(),29);//+1 for \0-terminated string...
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curSMPTE),25);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),21);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curMediatime),17);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),13);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curTimeScale),9);
Container->SetPayload((uint32_t)1,temp,8);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curBootstrapInfoVersion),4);
}

75
util/MP4/box_afra.cpp Normal file
View file

@ -0,0 +1,75 @@
#include "box.cpp"
#include <vector>
struct afra_record {
uint32_t Time;
uint32_t Offset;
};//afra_record
class Box_afra {
public:
Box_afra( );
~Box_afra();
Box * GetBox();
void SetTimeScale( uint32_t Scale = 1 );
void AddEntry( uint32_t Time = 0, uint32_t SampleOffset = 0, uint32_t Offset = 0 );
void WriteContent( );
private:
void SetReserved( );
void SetDefaults( );
Box * Container;
uint32_t CurrentTimeScale;
std::vector<afra_record> Entries;
};//Box_ftyp Class
Box_afra::Box_afra( ) {
Container = new Box( 0x61667261 );
SetReserved( );
SetDefaults( );
}
Box_afra::~Box_afra() {
delete Container;
}
Box * Box_afra::GetBox() {
return Container;
}
void Box_afra::SetDefaults( ) {
SetTimeScale( );
}
void Box_afra::SetReserved( ) {
uint8_t * temp = new uint8_t[1];
temp[0] = 0;
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),1);
Container->SetPayload((uint32_t)1,temp);
}
void Box_afra::SetTimeScale( uint32_t Scale ) {
CurrentTimeScale = Scale;
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Scale),5);
}
void Box_afra::AddEntry( uint32_t Time, uint32_t SampleOffset, uint32_t Offset ) {
if(Offset >= Entries.size()) {
Entries.resize(Offset+1);
}
Entries[Offset].Time = Time;
Entries[Offset].Offset = SampleOffset;
}
void Box_afra::WriteContent( ) {
Container->ResetPayload();
SetReserved( );
if(!Entries.empty()) {
for(int32_t i = Entries.size() -1; i >= 0; i--) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].Offset),(i*12)+21);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].Time),(i*12)+17);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),(i*12)+13);
}
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries.size()),9);
}

100
util/MP4/box_afrt.cpp Normal file
View file

@ -0,0 +1,100 @@
#include "box.cpp"
#include <string>
#include <vector>
struct afrt_fragmentrunentry {
uint32_t FirstFragment;
uint32_t FirstFragmentTimestamp; //write as uint64_t
uint32_t FragmentDuration;
uint8_t DiscontinuityIndicator;//if FragmentDuration == 0
};//afrt_fragmentrunentry
class Box_afrt {
public:
Box_afrt( );
~Box_afrt();
Box * GetBox();
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;
Box * Container;
};//Box_ftyp Class
Box_afrt::Box_afrt( ) {
Container = new Box( 0x61667274 );
}
Box_afrt::~Box_afrt() {
delete Container;
}
Box * Box_afrt::GetBox() {
return Container;
}
void Box_afrt::SetUpdate( bool Update ) {
isUpdate = Update;
}
void Box_afrt::AddQualityEntry( std::string Quality, uint32_t Offset ) {
if(Offset >= QualitySegmentUrlModifiers.size()) {
QualitySegmentUrlModifiers.resize(Offset+1);
}
QualitySegmentUrlModifiers[Offset] = Quality;
}
void Box_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;
FragmentRunEntryTable[Offset].DiscontinuityIndicator = Discontinuity;
}
void Box_afrt::SetDefaults( ) {
SetUpdate( );
SetTimeScale( );
}
void Box_afrt::SetTimeScale( uint32_t Scale ) {
curTimeScale = Scale;
}
void Box_afrt::WriteContent( ) {
std::string serializedQualities = "";
std::string serializedFragmentEntries = "";
Container->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));
serializedFragmentEntries.append((char*)Box::uint32_to_uint8(0));
serializedFragmentEntries.append((char*)Box::uint32_to_uint8(FragmentRunEntryTable[i].FirstFragmentTimestamp));
serializedFragmentEntries.append((char*)Box::uint32_to_uint8(FragmentRunEntryTable[i].FragmentDuration));
if(FragmentRunEntryTable[i].FragmentDuration == 0) {
serializedFragmentEntries.append((char*)Box::uint8_to_uint8(FragmentRunEntryTable[i].DiscontinuityIndicator));
}
}
uint32_t OffsetFragmentRunEntryCount = 9 + serializedQualities.size();
Container->SetPayload((uint32_t)serializedFragmentEntries.size(),(uint8_t*)serializedFragmentEntries.c_str(),OffsetFragmentRunEntryCount+4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(FragmentRunEntryTable.size()),OffsetFragmentRunEntryCount);
Container->SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),9);
Container->SetPayload((uint32_t)1,Box::uint8_to_uint8(QualitySegmentUrlModifiers.size()),8);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curTimeScale));
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8((isUpdate ? 1 : 0)));
}

63
util/MP4/box_amhp.cpp Normal file
View file

@ -0,0 +1,63 @@
#include "box.cpp"
#include <string>
#include <vector>
struct amhp_record {
uint8_t HintTrackMode;
uint8_t Settings;
uint8_t TrailerDefaultSize;
};//stsc_record
class Box_amhp {
public:
Box_amhp( );
~Box_amhp();
Box * GetBox();
void SetReserved( );
void AddEntry( uint8_t HintTrackMode, uint8_t Settings, uint8_t TrailerDefaultSize, uint32_t Offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<amhp_record> Entries;
};//Box_ftyp Class
Box_amhp::Box_amhp( ) {
Container = new Box( 0x616D6870 );
SetReserved();
}
Box_amhp::~Box_amhp() {
delete Container;
}
Box * Box_amhp::GetBox() {
return Container;
}
void Box_amhp::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_amhp::AddEntry( uint8_t HintTrackMode, uint8_t Settings, uint8_t TrailerDefaultSize, uint32_t Offset ) {
if(Offset >= Entries.size()) {
Entries.resize(Offset+1);
}
Entries[Offset].HintTrackMode = HintTrackMode;
Entries[Offset].Settings = Settings;
Entries[Offset].TrailerDefaultSize = TrailerDefaultSize;
}
void Box_amhp::WriteContent( ) {
Container->ResetPayload();
SetReserved( );
if(!Entries.empty()) {
for(int32_t i = Entries.size() -1; i >= 0; i--) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].TrailerDefaultSize),(i*12)+16);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].Settings),(i*12)+12);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].HintTrackMode),(i*12)+8);
}
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries.size()),4);
}

81
util/MP4/box_asrt.cpp Normal file
View file

@ -0,0 +1,81 @@
#include "box.cpp"
#include <string>
#include <vector>
struct asrt_segmentrunentry {
uint32_t FirstSegment;
uint32_t FragmentsPerSegment;
};//abst_qualityentry
class Box_asrt {
public:
Box_asrt( );
~Box_asrt();
Box * GetBox();
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( );
private:
void SetDefaults( );
bool isUpdate;
std::vector<std::string> QualitySegmentUrlModifiers;
std::vector<asrt_segmentrunentry> SegmentRunEntryTable;
Box * Container;
};//Box_ftyp Class
Box_asrt::Box_asrt( ) {
Container = new Box( 0x61737274 );
}
Box_asrt::~Box_asrt() {
delete Container;
}
Box * Box_asrt::GetBox() {
return Container;
}
void Box_asrt::SetUpdate( bool Update ) {
isUpdate = Update;
}
void Box_asrt::AddQualityEntry( std::string Quality, uint32_t Offset ) {
if(Offset >= QualitySegmentUrlModifiers.size()) {
QualitySegmentUrlModifiers.resize(Offset+1);
}
QualitySegmentUrlModifiers[Offset] = Quality;
}
void Box_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 Box_asrt::SetDefaults( ) {
SetUpdate( );
}
void Box_asrt::WriteContent( ) {
std::string serializedQualities = "";
Container->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 ++ ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable[i].FragmentsPerSegment),(8*i)+OffsetSegmentRunEntryCount+8);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable[i].FirstSegment),(8*i)+OffsetSegmentRunEntryCount+4);
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SegmentRunEntryTable.size()),OffsetSegmentRunEntryCount);
Container->SetPayload((uint32_t)serializedQualities.size(),(uint8_t*)serializedQualities.c_str(),5);
Container->SetPayload((uint32_t)1,Box::uint8_to_uint8(QualitySegmentUrlModifiers.size()),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8((isUpdate ? 1 : 0)));
}

86
util/MP4/box_avcC.cpp Normal file
View file

@ -0,0 +1,86 @@
#include "box.cpp"
#include <string>
class Box_avcC {
public:
Box_avcC( );
~Box_avcC();
Box * GetBox();
void SetDataReferenceIndex( uint16_t DataReferenceIndex = 1 );
void SetWidth( uint16_t Width = 0 );
void SetHeight( uint16_t Height = 0 );
void SetResolution ( uint32_t Horizontal = 0x00480000, uint32_t Vertical = 0x00480000 );
void SetFrameCount ( uint16_t FrameCount = 1 );
void SetCompressorName ( std::string CompressorName = "");
void SetDepth ( uint16_t Depth = 0x0018 );
private:
Box * Container;
void SetReserved( );
void SetDefaults( );
};//Box_ftyp Class
Box_avcC::Box_avcC( ) {
Container = new Box( 0x61766343 );
SetReserved();
SetDefaults();
}
Box_avcC::~Box_avcC() {
delete Container;
}
Box * Box_avcC::GetBox() {
return Container;
}
void Box_avcC::SetDataReferenceIndex( uint16_t DataReferenceIndex ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( DataReferenceIndex ),6);
}
void Box_avcC::SetWidth( uint16_t Width ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( Width ),24);
}
void Box_avcC::SetHeight( uint16_t Height ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( Height ),26);
}
void Box_avcC::SetResolution ( uint32_t Horizontal, uint32_t Vertical ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( Vertical ),32);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( Horizontal ),28);
}
void Box_avcC::SetFrameCount ( uint16_t FrameCount ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( FrameCount ),40);
}
void Box_avcC::SetCompressorName ( std::string CompressorName ) {
uint8_t * Printable = new uint8_t[1];
Printable[0] = std::min( (unsigned int)31, CompressorName.size() );
Container->SetPayload((uint32_t)Printable[0],(uint8_t*)CompressorName.c_str(),43);
Container->SetPayload((uint32_t)1, Printable ,42);
}
void Box_avcC::SetDepth ( uint16_t Depth ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( Depth ),74);
}
void Box_avcC::SetReserved( ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( (uint16_t)-1 ),76);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),36);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),20);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),16);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),12);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),8);
Container->SetPayload((uint32_t)4,Box::uint16_to_uint8(0),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_avcC::SetDefaults( ) {
SetWidth( );
SetHeight( );
SetDepth ( );
SetFrameCount ( );
SetResolution ( );
}

43
util/MP4/box_dinf.cpp Normal file
View file

@ -0,0 +1,43 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_dinf {
public:
Box_dinf();
~Box_dinf();
Box * GetBox();
void AddContent( Box * newcontent );
void WriteContent( );
private:
Box * Container;
Box * Content;
};//Box_ftyp Class
Box_dinf::Box_dinf( ) {
Container = new Box( 0x64696E66 );
}
Box_dinf::~Box_dinf() {
delete Container;
}
Box * Box_dinf::GetBox() {
return Container;
}
void Box_dinf::AddContent( Box * newcontent ) {
if(Content) {
delete Content;
Content = NULL;
}
Content = newcontent;
}
void Box_dinf::WriteContent( ) {
Container->ResetPayload( );
std::string serializedbox = "";
serializedbox.append((char*)Content->GetBoxedData(),Content->GetBoxedDataSize());
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

58
util/MP4/box_dref.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_dref {
public:
Box_dref();
~Box_dref();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
void SetReserved( );
std::vector<Box *> Content;
};//Box_ftyp Class
Box_dref::Box_dref( ) {
Container = new Box( 0x64726566 );
SetReserved( );
}
Box_dref::~Box_dref() {
delete Container;
}
Box * Box_dref::GetBox() {
return Container;
}
void Box_dref::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_dref::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str(),4);
SetReserved( );
}
void Box_dref::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}

55
util/MP4/box_esds.cpp Normal file
View file

@ -0,0 +1,55 @@
#include "box.cpp"
#include <string>
class Box_esds {
public:
Box_esds( );
~Box_esds();
Box * GetBox();
void SetDataReferenceIndex( uint16_t DataReferenceIndex = 1);
void SetChannelCount( uint16_t Count = 2 );
void SetSampleSize( uint16_t Size = 16 );
private:
Box * Container;
void SetReserved( );
void SetDefaults( );
};//Box_ftyp Class
Box_esds::Box_esds( ) {
Container = new Box( 0x65736473 );
SetReserved();
SetDefaults();
}
Box_esds::~Box_esds() {
delete Container;
}
Box * Box_esds::GetBox() {
return Container;
}
void Box_esds::SetDataReferenceIndex( uint16_t DataReferenceIndex ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( DataReferenceIndex ),6);
}
void Box_esds::SetChannelCount( uint16_t Count ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( Count ),16);
}
void Box_esds::SetSampleSize( uint16_t Size ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( Size ),18);
}
void Box_esds::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( 0 ),20);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8( 0 ),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( 0 ));
}
void Box_esds::SetDefaults( ) {
SetSampleSize( );
SetChannelCount( );
SetDataReferenceIndex( );
}

39
util/MP4/box_ftyp.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "box.cpp"
class Box_ftyp {
public:
Box_ftyp( );
~Box_ftyp();
Box * GetBox();
void SetMajorBrand( uint32_t MajorBrand = 0x66347620 );
void SetMinorBrand( uint32_t MinorBrand = 0x1 );
private:
void SetDefaults( );
Box * Container;
};//Box_ftyp Class
Box_ftyp::Box_ftyp( ) {
Container = new Box( 0x66747970 );
SetDefaults( );
}
Box_ftyp::~Box_ftyp() {
delete Container;
}
Box * Box_ftyp::GetBox() {
return Container;
}
void Box_ftyp::SetMajorBrand( uint32_t MajorBrand ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(MajorBrand));
}
void Box_ftyp::SetMinorBrand( uint32_t MinorBrand ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(MinorBrand),4);
}
void Box_ftyp::SetDefaults( ) {
SetMinorBrand( );
SetMajorBrand( );
}

59
util/MP4/box_hdlr.cpp Normal file
View file

@ -0,0 +1,59 @@
#include "box.cpp"
#include <string>
class Box_hdlr {
public:
Box_hdlr( );
~Box_hdlr();
Box * GetBox();
void SetHandlerType( uint32_t HandlerType = 0 );
void SetName ( std::string Name = "" );
private:
Box * Container;
void SetReserved( );
void SetDefaults( );
uint32_t CurrentHandlerType;
};//Box_ftyp Class
Box_hdlr::Box_hdlr( ) {
Container = new Box( 0x68646C72 );
CurrentHandlerType = 0;
SetReserved();
}
Box_hdlr::~Box_hdlr() {
delete Container;
}
Box * Box_hdlr::GetBox() {
return Container;
}
void Box_hdlr::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),20);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),16);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),12);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_hdlr::SetHandlerType( uint32_t HandlerType ) {
if( HandlerType != 0 ) {
CurrentHandlerType = HandlerType;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(CurrentHandlerType),8);
}
void Box_hdlr::SetName ( std::string Name ) {
char * tmp = new char[Name.size()+1];
strcpy(tmp,Name.c_str());
Container->ResetPayload();
SetReserved();
SetHandlerType(0);
Container->SetPayload((uint32_t)strlen(tmp)+1,(uint8_t*)tmp,24);
}
void Box_hdlr::SetDefaults( ) {
SetName( );
SetHandlerType( );
}

57
util/MP4/box_hmhd.cpp Normal file
View file

@ -0,0 +1,57 @@
#include "box.cpp"
class Box_hmhd {
public:
Box_hmhd( );
~Box_hmhd();
Box * GetBox();
void SetMaxPDUSize( uint16_t Size = 0 );
void SetAvgPDUSize( uint16_t Size = 0 );
void SetMaxBitRate( uint32_t Rate = 0 );
void SetAvgBitRate( uint32_t Rate = 0 );
private:
Box * Container;
void SetReserved( );
void SetDefaults( );
};//Box_ftyp Class
Box_hmhd::Box_hmhd( ) {
Container = new Box( 0x686D6864 );
SetDefaults();
SetReserved();
}
Box_hmhd::~Box_hmhd() {
delete Container;
}
Box * Box_hmhd::GetBox() {
return Container;
}
void Box_hmhd::SetMaxPDUSize( uint16_t Size ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(Size),4);
}
void Box_hmhd::SetAvgPDUSize( uint16_t Size ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(Size),6);
}
void Box_hmhd::SetMaxBitRate( uint32_t Rate ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Rate),8);
}
void Box_hmhd::SetAvgBitRate( uint32_t Rate ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Rate),12);
}
void Box_hmhd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),16);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_hmhd::SetDefaults( ) {
SetAvgBitRate( );
SetMaxBitRate( );
SetAvgPDUSize( );
SetMaxPDUSize( );
}

37
util/MP4/box_includes.h Normal file
View file

@ -0,0 +1,37 @@
#include "box_abst.cpp"
#include "box_afra.cpp"
#include "box_afrt.cpp"
#include "box_amhp.cpp"
#include "box_asrt.cpp"
#include "box_avcC.cpp"
#include "box_dinf.cpp"
#include "box_dref.cpp"
#include "box_esds.cpp"
#include "box_ftyp.cpp"
#include "box_hdlr.cpp"
#include "box_hmhd.cpp"
#include "box_mdat.cpp"
#include "box_mdhd.cpp"
#include "box_mdia.cpp"
#include "box_mfhd.cpp"
#include "box_minf.cpp"
#include "box_moof.cpp"
#include "box_moov.cpp"
#include "box_mvex.cpp"
#include "box_mvhd.cpp"
#include "box_nmhd.cpp"
#include "box_rtmp.cpp"
#include "box_smhd.cpp"
#include "box_stbl.cpp"
#include "box_stco.cpp"
#include "box_stsc.cpp"
#include "box_stsd.cpp"
#include "box_stts.cpp"
#include "box_tfhd.cpp"
#include "box_tkhd.cpp"
#include "box_traf.cpp"
#include "box_trak.cpp"
#include "box_trex.cpp"
#include "box_trun.cpp"
#include "box_url.cpp"
#include "box_vmhd.cpp"

29
util/MP4/box_mdat.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_mdat {
public:
Box_mdat();
~Box_mdat();
Box * GetBox();
void SetContent( uint8_t * NewData, uint32_t DataLength , uint32_t offset = 0 );
private:
Box * Container;
};//Box_ftyp Class
Box_mdat::Box_mdat( ) {
Container = new Box( 0x6D646174 );
}
Box_mdat::~Box_mdat() {
delete Container;
}
Box * Box_mdat::GetBox() {
return Container;
}
void Box_mdat::SetContent( uint8_t * NewData, uint32_t DataLength , uint32_t Offset ) {
Container->SetPayload(DataLength,NewData,Offset);
}

88
util/MP4/box_mdhd.cpp Normal file
View file

@ -0,0 +1,88 @@
#include "box.cpp"
#include <ctime>
#define SECONDS_DIFFERENCE 2082844800
class Box_mdhd {
public:
Box_mdhd( );
~Box_mdhd();
Box * GetBox();
void SetCreationTime( uint32_t TimeStamp = 0 );
void SetModificationTime( uint32_t TimeStamp = 0 );
void SetTimeScale( uint32_t TimeUnits = 0 );
void SetDurationTime( uint32_t TimeUnits = 0 );
void SetLanguage( uint8_t Firstchar = 'n', uint8_t Secondchar = 'l', uint8_t Thirdchar = 'd' );
private:
void SetReserved();
void SetDefaults();
Box * Container;
};//Box_ftyp Class
Box_mdhd::Box_mdhd( ) {
Container = new Box( 0x6D646864 );
}
Box_mdhd::~Box_mdhd() {
delete Container;
}
Box * Box_mdhd::GetBox() {
return Container;
}
void Box_mdhd::SetCreationTime( uint32_t TimeStamp ) {
uint32_t CreationTime;
if(!TimeStamp) {
CreationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
CreationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(CreationTime),4);
}
void Box_mdhd::SetModificationTime( uint32_t TimeStamp ) {
uint32_t ModificationTime;
if(!TimeStamp) {
ModificationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
ModificationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(ModificationTime),8);
}
void Box_mdhd::SetTimeScale( uint32_t TimeUnits ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TimeUnits),12);
}
void Box_mdhd::SetDurationTime( uint32_t TimeUnits ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TimeUnits),16);
}
void Box_mdhd::SetLanguage( uint8_t Firstchar, uint8_t Secondchar, uint8_t Thirdchar ) {
uint8_t FirstByte = 0;
uint8_t SecondByte = 0;
Firstchar -= 0x60;
Secondchar -= 0x60;
Thirdchar -= 0x60;
FirstByte += (Firstchar << 2);
FirstByte += (Secondchar >> 3);
SecondByte += (Secondchar << 5);
SecondByte += Thirdchar;
Container->SetPayload((uint32_t)1,&SecondByte,21);
Container->SetPayload((uint32_t)1,&FirstByte,20);
}
void Box_mdhd::SetReserved() {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(0),22);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_mdhd::SetDefaults() {
SetLanguage();
SetDurationTime();
SetTimeScale();
SetModificationTime();
SetCreationTime();
}

51
util/MP4/box_mdia.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_mdia {
public:
Box_mdia();
~Box_mdia();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_mdia::Box_mdia( ) {
Container = new Box( 0x6D646961 );
}
Box_mdia::~Box_mdia() {
delete Container;
}
Box * Box_mdia::GetBox() {
return Container;
}
void Box_mdia::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_mdia::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

39
util/MP4/box_mfhd.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "box.cpp"
class Box_mfhd {
public:
Box_mfhd( );
~Box_mfhd();
Box * GetBox();
void SetSequenceNumber( uint32_t SequenceNumber = 1 );
private:
void SetDefaults( );
void SetReserved( );
Box * Container;
};//Box_ftyp Class
Box_mfhd::Box_mfhd( ) {
Container = new Box( 0x6D666864 );
SetDefaults( );
SetReserved( );
}
Box_mfhd::~Box_mfhd() {
delete Container;
}
Box * Box_mfhd::GetBox() {
return Container;
}
void Box_mfhd::SetDefaults( ) {
SetSequenceNumber( );
}
void Box_mfhd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_mfhd::SetSequenceNumber( uint32_t SequenceNumber ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SequenceNumber),4);
}

51
util/MP4/box_minf.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_minf {
public:
Box_minf();
~Box_minf();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_minf::Box_minf( ) {
Container = new Box( 0x6D696E66 );
}
Box_minf::~Box_minf() {
delete Container;
}
Box * Box_minf::GetBox() {
return Container;
}
void Box_minf::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_minf::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

51
util/MP4/box_moof.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_moof {
public:
Box_moof();
~Box_moof();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_moof::Box_moof( ) {
Container = new Box( 0x6D6F6F66 );
}
Box_moof::~Box_moof() {
delete Container;
}
Box * Box_moof::GetBox() {
return Container;
}
void Box_moof::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_moof::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

51
util/MP4/box_moov.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_moov {
public:
Box_moov();
~Box_moov();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_moov::Box_moov( ) {
Container = new Box( 0x6D6F6F76 );
}
Box_moov::~Box_moov() {
delete Container;
}
Box * Box_moov::GetBox() {
return Container;
}
void Box_moov::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_moov::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

51
util/MP4/box_mvex.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_mvex {
public:
Box_mvex();
~Box_mvex();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_mvex::Box_mvex( ) {
Container = new Box( 0x6D866578 );
}
Box_mvex::~Box_mvex() {
delete Container;
}
Box * Box_mvex::GetBox() {
return Container;
}
void Box_mvex::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_mvex::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

113
util/MP4/box_mvhd.cpp Normal file
View file

@ -0,0 +1,113 @@
#include "box.cpp"
#include <ctime>
#define SECONDS_DIFFERENCE 2082844800
class Box_mvhd {
public:
Box_mvhd( );
~Box_mvhd();
Box * GetBox();
void SetCreationTime( uint32_t TimeStamp = 0 );
void SetModificationTime( uint32_t TimeStamp = 0 );
void SetTimeScale( uint32_t TimeUnits = 1 );
void SetDurationTime( uint32_t TimeUnits = 0 );
void SetRate( uint32_t Rate = 0x00010000 );
void SetVolume( uint16_t Volume = 0x0100 );
void SetNextTrackID( uint32_t TrackID = 0xFFFFFFFF );
private:
void SetReserved();
void SetDefaults();
Box * Container;
};//Box_ftyp Class
Box_mvhd::Box_mvhd( ) {
Container = new Box( 0x6D766864 );
SetDefaults();
SetReserved();
}
Box_mvhd::~Box_mvhd() {
delete Container;
}
Box * Box_mvhd::GetBox() {
return Container;
}
void Box_mvhd::SetCreationTime( uint32_t TimeStamp ) {
uint32_t CreationTime;
if(!TimeStamp) {
CreationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
CreationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(CreationTime),4);
}
void Box_mvhd::SetModificationTime( uint32_t TimeStamp ) {
uint32_t ModificationTime;
if(!TimeStamp) {
ModificationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
ModificationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(ModificationTime),8);
}
void Box_mvhd::SetTimeScale( uint32_t TimeUnits ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TimeUnits),12);
}
void Box_mvhd::SetDurationTime( uint32_t TimeUnits ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TimeUnits),16);
}
void Box_mvhd::SetRate( uint32_t Rate ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Rate),20);
}
void Box_mvhd::SetVolume( uint16_t Volume ) {
Container->SetPayload((uint32_t)4,Box::uint16_to_uint8(Volume),24);
}
void Box_mvhd::SetNextTrackID( uint32_t TrackID ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TrackID),92);
}
void Box_mvhd::SetReserved() {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),88);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),84);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),80);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),76);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),72);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),68);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x40000000),64);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),60);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),56);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),52);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x00010000),48);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),44);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),40);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),36);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x00010000),32);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),28);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),24);
Container->SetPayload((uint32_t)4,Box::uint16_to_uint8(0),22);
Container->SetPayload((uint32_t)4,Box::uint16_to_uint8(0));
}
void Box_mvhd::SetDefaults() {
SetCreationTime();
SetModificationTime();
SetDurationTime();
SetNextTrackID();
SetRate();
SetVolume();
SetTimeScale();
}

28
util/MP4/box_nmhd.cpp Normal file
View file

@ -0,0 +1,28 @@
#include "box.cpp"
class Box_nmhd {
public:
Box_nmhd( );
~Box_nmhd();
Box * GetBox();
private:
Box * Container;
void SetReserved( );
};//Box_ftyp Class
Box_nmhd::Box_nmhd( ) {
Container = new Box( 0x6E6D6864 );
SetReserved();
}
Box_nmhd::~Box_nmhd() {
delete Container;
}
Box * Box_nmhd::GetBox() {
return Container;
}
void Box_nmhd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}

89
util/MP4/box_rtmp.cpp Normal file
View file

@ -0,0 +1,89 @@
#include "box.cpp"
#include <string>
class Box_rtmp {
public:
Box_rtmp( );
~Box_rtmp();
Box * GetBox();
void SetDataReferenceIndex( uint16_t NewIndex = 0 );
void SetHintTrackVersion( uint16_t NewVersion = 1 );
void SetHighestCompatibleVersion( uint16_t NewVersion = 1 );
void SetMaxPacketSize( uint16_t NewSize = 0xFFFF );
void AddContent( Box * newcontent );
void WriteContent( );
private:
void SetReserved( );
void SetDefaults( );
uint16_t CurrentReferenceIndex;
uint16_t CurrentHintTrackVersion;
uint16_t CurrentHighestCompatibleVersion;
uint16_t CurrentMaxPacketSize;
Box * Container;
Box * Content;
};//Box_ftyp Class
Box_rtmp::Box_rtmp( ) {
Container = new Box( 0x72746D70 );
SetReserved();
SetDefaults();
}
Box_rtmp::~Box_rtmp() {
delete Container;
}
Box * Box_rtmp::GetBox() {
return Container;
}
void Box_rtmp::SetReserved( ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(CurrentMaxPacketSize),12);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(CurrentHighestCompatibleVersion),10);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(CurrentHintTrackVersion),8);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(CurrentReferenceIndex),6);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),2);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(0));
}
void Box_rtmp::SetDefaults( ) {
SetDataReferenceIndex( );
SetHintTrackVersion( );
SetHighestCompatibleVersion( );
SetMaxPacketSize( );
}
void Box_rtmp::SetDataReferenceIndex( uint16_t NewIndex ) {
CurrentReferenceIndex = NewIndex;
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(NewIndex),6);
}
void Box_rtmp::SetHintTrackVersion( uint16_t NewVersion ) {
CurrentHintTrackVersion = NewVersion;
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(NewVersion),8);
}
void Box_rtmp::SetHighestCompatibleVersion( uint16_t NewVersion ) {
CurrentHighestCompatibleVersion = NewVersion;
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(NewVersion),10);
}
void Box_rtmp::SetMaxPacketSize( uint16_t NewSize ) {
CurrentMaxPacketSize = NewSize;
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(NewSize),12);
}
void Box_rtmp::AddContent( Box * newcontent ) {
if(Content) {
delete Content;
Content = NULL;
}
Content = newcontent;
}
void Box_rtmp::WriteContent( ) {
Container->ResetPayload( );
SetReserved( );
std::string serializedbox = "";
serializedbox.append((char*)Content->GetBoxedData(),Content->GetBoxedDataSize());
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str(),14);
}

29
util/MP4/box_smhd.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "box.cpp"
class Box_smhd {
public:
Box_smhd( );
~Box_smhd();
Box * GetBox();
private:
Box * Container;
void SetReserved( );
};//Box_ftyp Class
Box_smhd::Box_smhd( ) {
Container = new Box( 0x736D6864 );
SetReserved();
}
Box_smhd::~Box_smhd() {
delete Container;
}
Box * Box_smhd::GetBox() {
return Container;
}
void Box_smhd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}

51
util/MP4/box_stbl.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_stbl {
public:
Box_stbl();
~Box_stbl();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_stbl::Box_stbl( ) {
Container = new Box( 0x7374626C );
}
Box_stbl::~Box_stbl() {
delete Container;
}
Box * Box_stbl::GetBox() {
return Container;
}
void Box_stbl::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_stbl::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

58
util/MP4/box_stco.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "box.cpp"
#include <string>
#include <vector>
class Box_stco {
public:
Box_stco( );
~Box_stco();
Box * GetBox();
void AddOffset( uint32_t DataOffset, uint32_t Offset = 0 );
void SetOffsets( std::vector<uint32_t> NewOffsets );
void WriteContent( );
private:
Box * Container;
void SetReserved( );
std::vector<uint32_t> Offsets;
};//Box_ftyp Class
Box_stco::Box_stco( ) {
Container = new Box( 0x7374636F );
SetReserved();
}
Box_stco::~Box_stco() {
delete Container;
}
Box * Box_stco::GetBox() {
return Container;
}
void Box_stco::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_stco::AddOffset( uint32_t DataOffset, uint32_t Offset ) {
if(Offset >= Offsets.size()) {
Offsets.resize(Offset+1);
}
Offsets[Offset] = DataOffset;
}
void Box_stco::WriteContent( ) {
Container->ResetPayload();
SetReserved( );
if(!Offsets.empty()) {
for(int32_t i = Offsets.size() -1; i >= 0; i--) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Offsets[i]),(i*4)+8);
}
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Offsets.size()),4);
}
void Box_stco::SetOffsets( std::vector<uint32_t> NewOffsets ) {
Offsets = NewOffsets;
}

63
util/MP4/box_stsc.cpp Normal file
View file

@ -0,0 +1,63 @@
#include "box.cpp"
#include <string>
#include <vector>
struct stsc_record {
uint32_t FirstChunk;
uint32_t SamplesPerChunk;
uint32_t SampleDescIndex;
};//stsc_record
class Box_stsc {
public:
Box_stsc( );
~Box_stsc();
Box * GetBox();
void SetReserved( );
void AddEntry( uint32_t FirstChunk = 0, uint32_t SamplesPerChunk = 0, uint32_t SampleDescIndex = 0, uint32_t Offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<stsc_record> Entries;
};//Box_ftyp Class
Box_stsc::Box_stsc( ) {
Container = new Box( 0x73747363 );
SetReserved();
}
Box_stsc::~Box_stsc() {
delete Container;
}
Box * Box_stsc::GetBox() {
return Container;
}
void Box_stsc::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_stsc::AddEntry( uint32_t FirstChunk, uint32_t SamplesPerChunk, uint32_t SampleDescIndex, uint32_t Offset ) {
if(Offset >= Entries.size()) {
Entries.resize(Offset+1);
}
Entries[Offset].FirstChunk = FirstChunk;
Entries[Offset].SamplesPerChunk = SamplesPerChunk;
Entries[Offset].SampleDescIndex = SampleDescIndex;
}
void Box_stsc::WriteContent( ) {
Container->ResetPayload();
SetReserved( );
if(!Entries.empty()) {
for(int32_t i = Entries.size() -1; i >= 0; i--) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].SampleDescIndex),(i*12)+16);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].SamplesPerChunk),(i*12)+12);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].FirstChunk),(i*12)+8);
}
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries.size()),4);
}

59
util/MP4/box_stsd.cpp Normal file
View file

@ -0,0 +1,59 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_stsd {
public:
Box_stsd( );
~Box_stsd();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent();
private:
Box * Container;
void SetReserved();
std::vector<Box *> Content;
};//Box_ftyp Class
Box_stsd::Box_stsd( ) {
Container = new Box( 0x73747364 );
SetReserved();
}
Box_stsd::~Box_stsd() {
delete Container;
}
Box * Box_stsd::GetBox() {
return Container;
}
void Box_stsd::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_stsd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( 1 ),4);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8( 0 ),0);
}
void Box_stsd::WriteContent( ) {
Container->ResetPayload( );
SetReserved( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str(),8);
}

60
util/MP4/box_stts.cpp Normal file
View file

@ -0,0 +1,60 @@
#include "box.cpp"
#include <string>
#include <vector>
struct stts_record {
uint32_t SampleCount;
uint32_t SampleDelta;
};//stsc_record
class Box_stts {
public:
Box_stts( );
~Box_stts();
Box * GetBox();
void SetReserved( );
void AddEntry( uint32_t SampleCount, uint32_t SampleDelta, uint32_t Offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<stts_record> Entries;
};//Box_ftyp Class
Box_stts::Box_stts( ) {
Container = new Box( 0x73747473 );
SetReserved();
}
Box_stts::~Box_stts() {
delete Container;
}
Box * Box_stts::GetBox() {
return Container;
}
void Box_stts::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_stts::AddEntry( uint32_t SampleCount, uint32_t SampleDelta, uint32_t Offset ) {
if(Offset >= Entries.size()) {
Entries.resize(Offset+1);
}
Entries[Offset].SampleCount = SampleCount;
Entries[Offset].SampleDelta = SampleDelta;
}
void Box_stts::WriteContent( ) {
Container->ResetPayload();
SetReserved( );
if(!Entries.empty()) {
for(int32_t i = Entries.size() -1; i >= 0; i--) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].SampleDelta),(i*8)+12);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries[i].SampleCount),(i*8)+8);
}
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Entries.size()),4);
}

88
util/MP4/box_tfhd.cpp Normal file
View file

@ -0,0 +1,88 @@
#include "box.cpp"
class Box_tfhd {
public:
Box_tfhd( );
~Box_tfhd();
Box * GetBox();
void SetTrackID( uint32_t TrackID = 0 );
void SetBaseDataOffset( uint32_t Offset = 0 );//write as uint64_t
void SetSampleDescriptionIndex( uint32_t Index = 0 );
void SetDefaultSampleDuration( uint32_t Duration = 0 );
void SetDefaultSampleSize( uint32_t Size = 0 );
void WriteContent( );
private:
void SetDefaults( );
uint32_t curTrackID;
uint32_t curBaseDataOffset;
uint32_t curSampleDescriptionIndex;
uint32_t curDefaultSampleDuration;
uint32_t curDefaultSampleSize;
Box * Container;
};//Box_ftyp Class
Box_tfhd::Box_tfhd( ) {
Container = new Box( 0x74666864 );
SetDefaults( );
}
Box_tfhd::~Box_tfhd() {
delete Container;
}
Box * Box_tfhd::GetBox() {
return Container;
}
void Box_tfhd::SetTrackID( uint32_t TrackID ) {
curTrackID = TrackID;
}
void Box_tfhd::SetBaseDataOffset( uint32_t Offset ) {
curBaseDataOffset = Offset;
}
void Box_tfhd::SetSampleDescriptionIndex( uint32_t Index ) {
curSampleDescriptionIndex = Index;
}
void Box_tfhd::SetDefaultSampleDuration( uint32_t Duration ) {
curDefaultSampleDuration = Duration;
}
void Box_tfhd::SetDefaultSampleSize( uint32_t Size ) {
curDefaultSampleSize = Size;
}
void Box_tfhd::WriteContent( ) {
uint32_t curoffset;
uint32_t flags = 0 & ( curBaseDataOffset ? 0x1 : 0 ) & ( curSampleDescriptionIndex ? 0x2 : 0 ) & ( curDefaultSampleDuration ? 0x8 : 0 ) & ( curDefaultSampleSize ? 0x10 : 0 );
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(flags));
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curTrackID),4);
curoffset = 8;
if( curBaseDataOffset ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),curoffset);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curBaseDataOffset),curoffset+4);
curoffset += 8;
}
if( curSampleDescriptionIndex ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curSampleDescriptionIndex),curoffset);
curoffset += 8;
}
if( curDefaultSampleDuration ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curDefaultSampleDuration),curoffset);
curoffset += 8;
}
if( curDefaultSampleSize ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curDefaultSampleSize),curoffset);
curoffset += 8;
}
}
void Box_tfhd::SetDefaults( ) {
SetTrackID( );
SetBaseDataOffset( );
SetSampleDescriptionIndex( );
SetDefaultSampleDuration( );
SetDefaultSampleSize( );
}

117
util/MP4/box_tkhd.cpp Normal file
View file

@ -0,0 +1,117 @@
#include "box.cpp"
#include <ctime>
#define SECONDS_DIFFERENCE 2082844800
class Box_tkhd {
public:
Box_tkhd( );
~Box_tkhd();
Box * GetBox();
void SetCreationTime( uint32_t TimeStamp = 0 );
void SetModificationTime( uint32_t TimeStamp = 0 );
void SetDurationTime( uint32_t TimeUnits = 0 );
void SetWidth( uint16_t Width = 0 );
void SetHeight( uint16_t Height = 0 );
void SetFlags( bool Bit0 = true, bool Bit1 = true, bool Bit2 = true );
void SetVersion( uint32_t Version = 0 );
void SetTrackID( uint32_t TrackID = 0 );
private:
void SetReserved();
void SetDefaults();
Box * Container;
uint32_t CurrentFlags;
uint32_t CurrentVersion;
};//Box_ftyp Class
Box_tkhd::Box_tkhd( ) {
Container = new Box( 0x746B6864 );
CurrentVersion = 0;
CurrentFlags = 0;
}
Box_tkhd::~Box_tkhd() {
delete Container;
}
Box * Box_tkhd::GetBox() {
return Container;
}
void Box_tkhd::SetCreationTime( uint32_t TimeStamp ) {
uint32_t CreationTime;
if(!TimeStamp) {
CreationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
CreationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(CreationTime),4);
}
void Box_tkhd::SetModificationTime( uint32_t TimeStamp ) {
uint32_t ModificationTime;
if(!TimeStamp) {
ModificationTime = time(NULL) + SECONDS_DIFFERENCE;
} else {
ModificationTime = TimeStamp;
}
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(ModificationTime),8);
}
void Box_tkhd::SetDurationTime( uint32_t TimeUnits ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TimeUnits),16);
}
void Box_tkhd::SetReserved() {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x40000000),68);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),64);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),60);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),56);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x10000),52);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),48);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),44);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),40);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0x10000),36);
Container->SetPayload((uint32_t)4,Box::uint16_to_uint8(0),34);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),28);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),24);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),20);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0),12);
}
void Box_tkhd::SetVersion( uint32_t Version ) {
if ( Version >= 2 ) { return; }
CurrentVersion = Version;
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8((CurrentVersion<<24)&(CurrentFlags)));
}
void Box_tkhd::SetFlags( bool Bit0, bool Bit1, bool Bit2 ) {
CurrentFlags = (( Bit0 ? 0x80 : 0 ) + ( Bit1 ? 0x40 : 0 ) + ( Bit2 ? 0x20 : 0 )) << 16 ;
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8((CurrentVersion<<24)&(CurrentFlags)));
}
void Box_tkhd::SetTrackID( uint32_t TrackID ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(TrackID),12);
}
void Box_tkhd::SetWidth( uint16_t Width ) {
uint32_t ResultWidth = ( Width << 16 );
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(ResultWidth),72);
}
void Box_tkhd::SetHeight( uint16_t Height ) {
uint32_t ResultHeight = ( Height << 16 );
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(ResultHeight),76);
}
void Box_tkhd::SetDefaults() {
SetHeight();
SetWidth();
SetCreationTime();
SetModificationTime();
SetDurationTime();
SetFlags();
SetVersion();
SetTrackID();
}

51
util/MP4/box_traf.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_traf {
public:
Box_traf();
~Box_traf();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_traf::Box_traf( ) {
Container = new Box( 0x74726166 );
}
Box_traf::~Box_traf() {
delete Container;
}
Box * Box_traf::GetBox() {
return Container;
}
void Box_traf::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_traf::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

51
util/MP4/box_trak.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "box.cpp"
#include <vector>
#include <string>
class Box_trak {
public:
Box_trak();
~Box_trak();
Box * GetBox();
void AddContent( Box * newcontent, uint32_t offset = 0 );
void WriteContent( );
private:
Box * Container;
std::vector<Box *> Content;
};//Box_ftyp Class
Box_trak::Box_trak( ) {
Container = new Box( 0x7472616B );
}
Box_trak::~Box_trak() {
delete Container;
}
Box * Box_trak::GetBox() {
return Container;
}
void Box_trak::AddContent( Box * newcontent, uint32_t offset ) {
if( offset >= Content.size() ) {
Content.resize(offset+1);
}
if( Content[offset] ) {
delete Content[offset];
}
Content[offset] = newcontent;
}
void Box_trak::WriteContent( ) {
Container->ResetPayload( );
Box * current;
std::string serializedbox = "";
for( uint32_t i = 0; i < Content.size(); i++ ) {
current=Content[i];
if( current ) {
serializedbox.append((char*)current->GetBoxedData(),current->GetBoxedDataSize());
}
}
Container->SetPayload((uint32_t)serializedbox.size(),(uint8_t*)serializedbox.c_str());
}

59
util/MP4/box_trex.cpp Normal file
View file

@ -0,0 +1,59 @@
#include "box.cpp"
class Box_trex {
public:
Box_trex( );
~Box_trex();
Box * GetBox();
void SetTrackID( uint32_t Id = 0 );
void SetSampleDescriptionIndex( uint32_t Index = 0 );
void SetSampleDuration( uint32_t Duration = 0 );
void SetSampleSize( uint32_t Size = 0 );
private:
void SetReserved( );
void SetDefaults( );
Box * Container;
};//Box_ftyp Class
Box_trex::Box_trex( ) {
Container = new Box( 0x74726578 );
SetReserved( );
SetDefaults( );
}
Box_trex::~Box_trex() {
delete Container;
}
Box * Box_trex::GetBox() {
return Container;
}
void Box_trex::SetDefaults( ) {
SetTrackID( );
SetSampleDescriptionIndex( );
SetSampleDuration( );
SetSampleSize( );
}
void Box_trex::SetReserved( ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(1),22);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(0),20);
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(0));
}
void Box_trex::SetTrackID( uint32_t Id ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Id),4);
}
void Box_trex::SetSampleDescriptionIndex( uint32_t Index ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Index),8);
}
void Box_trex::SetSampleDuration( uint32_t Duration ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Duration),12);
}
void Box_trex::SetSampleSize( uint32_t Size ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(Size),16);
}

68
util/MP4/box_trun.cpp Normal file
View file

@ -0,0 +1,68 @@
#include "box.cpp"
#include <vector>
struct trun_sampleinformationstructure {
uint32_t SampleDuration;
uint32_t SampleSize;
};
class Box_trun {
public:
Box_trun( );
~Box_trun();
Box * GetBox();
void SetDataOffset( uint32_t Offset = 0 );
void AddSampleInformation( uint32_t SampleDuration = 0, uint32_t SampleSize = 0, uint32_t Offset = 0 );
void WriteContent( );
private:
void SetDefaults( );
bool setSampleDuration;
bool setSampleSize;
uint32_t curDataOffset;
std::vector<trun_sampleinformationstructure> SampleInfo;
Box * Container;
};//Box_ftyp Class
Box_trun::Box_trun( ) {
Container = new Box( 0x74666864 );
SetDefaults( );
}
Box_trun::~Box_trun() {
delete Container;
}
Box * Box_trun::GetBox() {
return Container;
}
void Box_trun::SetDataOffset( uint32_t Offset ) {
curDataOffset = Offset;
}
void Box_trun::WriteContent( ) {
uint32_t curoffset;
uint32_t flags = 0 & ( curDataOffset ? 0x1 : 0 ) & ( setSampleDuration ? 0x100 : 0 ) & ( setSampleSize ? 0x200 : 0 );
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(flags));
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SampleInfo.size()),4);
curoffset = 8;
if( curDataOffset ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(curDataOffset),curoffset);
curoffset += 4;
}
for( uint32_t i = 0; i < SampleInfo.size(); i++ ) {
if( setSampleDuration ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SampleInfo[i].SampleDuration),curoffset);
curoffset += 4;
}
if( setSampleSize ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(SampleInfo[i].SampleSize),curoffset);
curoffset += 4;
}
}
}
void Box_trun::SetDefaults( ) {
setSampleDuration = false;
setSampleSize = false;
}

23
util/MP4/box_url.cpp Normal file
View file

@ -0,0 +1,23 @@
#include "box.cpp"
class Box_url {
public:
Box_url( );
~Box_url();
Box * GetBox();
private:
Box * Container;
};//Box_ftyp Class
Box_url::Box_url( ) {
Container = new Box( 0x75726C20 );
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(1));
}
Box_url::~Box_url() {
delete Container;
}
Box * Box_url::GetBox() {
return Container;
}

45
util/MP4/box_vmhd.cpp Normal file
View file

@ -0,0 +1,45 @@
#include "box.cpp"
class Box_vmhd {
public:
Box_vmhd( );
~Box_vmhd();
Box * GetBox();
void SetGraphicsMode( uint16_t GraphicsMode = 0 );
void SetOpColor( uint16_t Red = 0, uint16_t Green = 0, uint16_t Blue = 0);
private:
Box * Container;
void SetReserved( );
void SetDefaults( );
};//Box_ftyp Class
Box_vmhd::Box_vmhd( ) {
Container = new Box( 0x766D6864 );
SetDefaults();
SetReserved();
}
Box_vmhd::~Box_vmhd() {
delete Container;
}
Box * Box_vmhd::GetBox() {
return Container;
}
void Box_vmhd::SetGraphicsMode( uint16_t GraphicsMode ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(GraphicsMode),8);
}
void Box_vmhd::SetOpColor( uint16_t Red, uint16_t Green, uint16_t Blue ) {
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(Blue),14);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(Green),12);
Container->SetPayload((uint32_t)2,Box::uint16_to_uint8(Red),10);
}
void Box_vmhd::SetReserved( ) {
Container->SetPayload((uint32_t)4,Box::uint32_to_uint8(1));
}
void Box_vmhd::SetDefaults( ) {
SetOpColor();
SetGraphicsMode();
}

583
util/MP4/interface.cpp Normal file
View file

@ -0,0 +1,583 @@
#include "box_includes.h"
#include <string>
class Interface {
public:
Interface();
~Interface();
void link();
uint32_t GetContentSize();
uint8_t * GetContents();
void SetWidth( uint16_t NewWidth );
void SetHeight( uint16_t NewHeight );
void SetDurationTime( uint32_t NewDuration, uint32_t Track );
void SetTimeScale( uint32_t NewUnitsPerSecond, uint32_t Track );
void AddSTTSEntry( uint32_t SampleCount, uint32_t SampleDelta, uint32_t Track );
void EmptySTTS( uint32_t Track );
void AddSTSCEntry( uint32_t FirstChunk, uint32_t SamplesPerChunk, uint32_t Track );
void EmptySTSC( uint32_t Track );
void SetOffsets( std::vector<uint32_t> NewOffsets, uint32_t Track );
void SetData( std::string data );
std::string GenerateLiveBootstrap( uint32_t CurMediaTime );
static std::string mdatFold(std::string data);
private:
void SetStaticDefaults();
void UpdateContents();
void WriteSTTS( uint32_t Track );
void WriteSTSC( uint32_t Track );
bool AllBoxesExist();
uint16_t Width;
uint16_t Height;
std::vector<uint32_t> Duration;
std::vector<uint32_t> UnitsPerSecond;
std::vector<stts_record> sttsvide;
std::vector<stts_record> sttssoun;
std::vector<stsc_record> stscvide;
std::vector<stsc_record> stscsoun;
Box_ftyp * ftyp;
Box_moov * moov;
Box_mvhd * mvhd;
Box_trak * trak_vide;
Box_tkhd * tkhd_vide;
Box_mdia * mdia_vide;
Box_mdhd * mdhd_vide;
Box_hdlr * hdlr_vide;
Box_minf * minf_vide;
Box_vmhd * vmhd_vide;
Box_dinf * dinf_vide;
Box_dref * dref_vide;
Box_url * url_vide;
Box_stbl * stbl_vide;
Box_stts * stts_vide;
Box_stsc * stsc_vide;
Box_stco * stco_vide;
Box_stsd * stsd_vide;
Box_avcC * avcC_vide;
Box_trak * trak_soun;
Box_tkhd * tkhd_soun;
Box_mdia * mdia_soun;
Box_mdhd * mdhd_soun;
Box_hdlr * hdlr_soun;
Box_minf * minf_soun;
Box_smhd * smhd_soun;
Box_dinf * dinf_soun;
Box_dref * dref_soun;
Box_url * url_soun;
Box_stbl * stbl_soun;
Box_stts * stts_soun;
Box_stsc * stsc_soun;
Box_stco * stco_soun;
Box_stsd * stsd_soun;
Box_esds * esds_soun;
Box_rtmp * rtmp;
Box_amhp * amhp;
Box_mvex * mvex;
Box_trex * trex_vide;
Box_trex * trex_soun;
Box_afra * afra;
Box_abst * abst;
Box_asrt * asrt;
Box_afrt * afrt;
Box_moof * moof;
Box_mfhd * mfhd;
Box_traf * traf_vide;
Box_tfhd * tfhd_vide;
Box_trun * trun_vide;
Box_traf * traf_soun;
Box_tfhd * tfhd_soun;
Box_trun * trun_soun;
};//Interface class
Interface::Interface() {
//Initializing local data
Width = 0;
Height = 0;
//Creating the boxes
ftyp = new Box_ftyp();
moov = new Box_moov();
mvhd = new Box_mvhd();
trak_vide = new Box_trak();
tkhd_vide = new Box_tkhd();
mdia_vide = new Box_mdia();
mdhd_vide = new Box_mdhd();
hdlr_vide = new Box_hdlr();
minf_vide = new Box_minf();
vmhd_vide = new Box_vmhd();
dinf_vide = new Box_dinf();
dref_vide = new Box_dref();
url_vide = new Box_url();
stbl_vide = new Box_stbl();
stts_vide = new Box_stts();
stsc_vide = new Box_stsc();
stco_vide = new Box_stco();
stsd_vide = new Box_stsd();
avcC_vide = new Box_avcC();
trak_soun = new Box_trak();
tkhd_soun = new Box_tkhd();
mdia_soun = new Box_mdia();
mdhd_soun = new Box_mdhd();
hdlr_soun = new Box_hdlr();
minf_soun = new Box_minf();
smhd_soun = new Box_smhd();
dinf_soun = new Box_dinf();
dref_soun = new Box_dref();
url_soun = new Box_url();
stbl_soun = new Box_stbl();
stts_soun = new Box_stts();
stsc_soun = new Box_stsc();
stco_soun = new Box_stco();
stsd_soun = new Box_stsd();
esds_soun = new Box_esds();
rtmp = new Box_rtmp();
amhp = new Box_amhp();
mvex = new Box_mvex();
trex_vide = new Box_trex();
trex_soun = new Box_trex();
afra = new Box_afra();
abst = new Box_abst();
asrt = new Box_asrt();
afrt = new Box_afrt();
moof = new Box_moof();
mfhd = new Box_mfhd();
traf_vide = new Box_traf();
tfhd_vide = new Box_tfhd();
trun_vide = new Box_trun();
traf_soun = new Box_traf();
tfhd_soun = new Box_tfhd();
trun_soun = new Box_trun();
//Set some values we already know won't change once the boxes have been created
SetStaticDefaults();
}
Interface::~Interface() {
//Deleting the boxes if they still exist.
if( trun_soun ) { delete trun_soun; trun_soun = NULL; }
if( tfhd_soun ) { delete tfhd_soun; tfhd_soun = NULL; }
if( traf_soun ) { delete traf_soun; traf_soun = NULL; }
if( trun_vide ) { delete trun_vide; trun_vide = NULL; }
if( tfhd_vide ) { delete tfhd_vide; tfhd_vide = NULL; }
if( traf_vide ) { delete traf_vide; traf_vide = NULL; }
if( mfhd ) { delete mfhd; mfhd = NULL; }
if( moof ) { delete moof; moof = NULL; }
if( afrt ) { delete afrt; afrt = NULL; }
if( asrt ) { delete asrt; asrt = NULL; }
if( abst ) { delete abst; abst = NULL; }
if( afra ) { delete afra; afra = NULL; }
if( trex_vide ) { delete trex_vide; trex_vide = NULL; }
if( trex_soun ) { delete trex_soun; trex_soun = NULL; }
if( mvex ) { delete mvex; mvex = NULL; }
if( amhp ) { delete amhp; amhp = NULL; }
if( rtmp ) { delete rtmp; rtmp = NULL; }
if( esds_soun ) { delete esds_soun; esds_soun = NULL; }
if( stsd_soun ) { delete stsd_soun; stsd_soun = NULL; }
if( stco_soun ) { delete stco_soun; stco_soun = NULL; }
if( stsc_soun ) { delete stsc_soun; stsc_soun = NULL; }
if( stts_soun ) { delete stts_soun; stts_soun = NULL; }
if( stbl_soun ) { delete stbl_soun; stbl_soun = NULL; }
if( url_soun ) { delete url_soun; url_soun = NULL; }
if( dref_soun ) { delete dref_soun; dref_soun = NULL; }
if( dinf_soun ) { delete dinf_soun; dinf_soun = NULL; }
if( minf_soun ) { delete minf_soun; minf_soun = NULL; }
if( hdlr_soun ) { delete hdlr_soun; hdlr_soun = NULL; }
if( mdhd_soun ) { delete mdhd_soun; mdhd_soun = NULL; }
if( mdia_soun ) { delete mdia_soun; mdia_soun = NULL; }
if( tkhd_soun ) { delete tkhd_soun; tkhd_soun = NULL; }
if( trak_soun ) { delete trak_soun; trak_soun = NULL; }
if( avcC_vide ) { delete avcC_vide; avcC_vide = NULL; }
if( stsd_vide ) { delete stsd_vide; stsd_vide = NULL; }
if( stco_vide ) { delete stco_vide; stco_vide = NULL; }
if( stsc_vide ) { delete stsc_vide; stsc_vide = NULL; }
if( stts_vide ) { delete stts_vide; stts_vide = NULL; }
if( stbl_vide ) { delete stbl_vide; stbl_vide = NULL; }
if( url_vide ) { delete url_vide; url_vide = NULL; }
if( dref_vide ) { delete dref_vide; dref_vide = NULL; }
if( dinf_vide ) { delete dinf_vide; dinf_vide = NULL; }
if( minf_vide ) { delete minf_vide; minf_vide = NULL; }
if( hdlr_vide ) { delete hdlr_vide; hdlr_vide = NULL; }
if( mdhd_vide ) { delete mdhd_vide; mdhd_vide = NULL; }
if( mdia_vide ) { delete mdia_vide; mdia_vide = NULL; }
if( tkhd_vide ) { delete tkhd_vide; tkhd_vide = NULL; }
if( trak_vide ) { delete trak_vide; trak_vide = NULL; }
if( mvhd ) { delete mvhd; mvhd = NULL; }
if( moov ) { delete moov; moov = NULL; }
if( ftyp ) { delete ftyp; ftyp = NULL; }
}
void Interface::link( ) {
//Linking Video Track
stsd_vide->AddContent(avcC_vide->GetBox());
stbl_vide->AddContent(stsd_vide->GetBox(),3);
stbl_vide->AddContent(stco_vide->GetBox(),2);
stbl_vide->AddContent(stsc_vide->GetBox(),1);
stbl_vide->AddContent(stts_vide->GetBox());
dref_vide->AddContent(url_vide->GetBox());
dinf_vide->AddContent(dref_vide->GetBox());
minf_vide->AddContent(stbl_vide->GetBox(),2);
minf_vide->AddContent(dinf_vide->GetBox(),1);
minf_vide->AddContent(vmhd_vide->GetBox());
mdia_vide->AddContent(minf_vide->GetBox(),2);
mdia_vide->AddContent(hdlr_vide->GetBox(),1);
mdia_vide->AddContent(mdhd_vide->GetBox());
trak_vide->AddContent(mdia_vide->GetBox(),1);
trak_vide->AddContent(tkhd_vide->GetBox());
//Linking Sound Track
stsd_soun->AddContent(esds_soun->GetBox());
stbl_soun->AddContent(stsd_soun->GetBox(),3);
stbl_soun->AddContent(stco_soun->GetBox(),2);
stbl_soun->AddContent(stsc_soun->GetBox(),1);
stbl_soun->AddContent(stts_soun->GetBox());
dref_soun->AddContent(url_soun->GetBox());
dinf_soun->AddContent(dref_soun->GetBox());
minf_soun->AddContent(stbl_soun->GetBox(),2);
minf_soun->AddContent(dinf_soun->GetBox(),1);
minf_soun->AddContent(smhd_soun->GetBox());
mdia_soun->AddContent(minf_soun->GetBox(),2);
mdia_soun->AddContent(hdlr_soun->GetBox(),1);
mdia_soun->AddContent(mdhd_soun->GetBox());
trak_soun->AddContent(mdia_soun->GetBox(),1);
trak_soun->AddContent(tkhd_soun->GetBox());
//Linking mvex
mvex->AddContent(trex_soun->GetBox(),2);
mvex->AddContent(trex_vide->GetBox(),1);
//Linking total file
moov->AddContent(mvex->GetBox(),3);
moov->AddContent(trak_soun->GetBox(),2);
moov->AddContent(trak_vide->GetBox(),1);
moov->AddContent(mvhd->GetBox());
rtmp->AddContent(amhp->GetBox());
//Linking ABST
abst->AddFragmentRunTable(afrt->GetBox());
abst->AddSegmentRunTable(asrt->GetBox());
//Linking TRAF_SOUN
traf_soun->AddContent( trun_soun->GetBox(),1);
traf_soun->AddContent( tfhd_soun->GetBox() );
//Linking TRAF_vide
traf_vide->AddContent( trun_vide->GetBox(),1);
traf_vide->AddContent( tfhd_vide->GetBox() );
//Linking MOOF
moof->AddContent(traf_soun->GetBox(),2);
moof->AddContent(traf_vide->GetBox(),1);
moof->AddContent(mfhd->GetBox());
}
uint32_t Interface::GetContentSize( ) {
return ftyp->GetBox( )->GetBoxedDataSize( ) + moov->GetBox( )->GetBoxedDataSize( ) + rtmp->GetBox( )->GetBoxedDataSize( );
}
uint8_t * Interface::GetContents( ) {
uint8_t * Result = new uint8_t[GetContentSize( )];
uint32_t Ftyp_Size = ftyp->GetBox( )->GetBoxedDataSize( );
uint32_t Moov_Size = moov->GetBox( )->GetBoxedDataSize( );
uint32_t Rtmp_Size = rtmp->GetBox( )->GetBoxedDataSize( );
memcpy(Result,ftyp->GetBox( )->GetBoxedData( ),Ftyp_Size);
memcpy(&Result[Ftyp_Size],moov->GetBox( )->GetBoxedData( ),Moov_Size);
memcpy(&Result[Ftyp_Size+Moov_Size],rtmp->GetBox( )->GetBoxedData( ),Rtmp_Size);
return Result;
}
void Interface::UpdateContents( ) {
if( !Width ) { fprintf(stderr,"WARNING: Width not set!\n"); }
if( !Height ) { fprintf(stderr,"WARNING: Height not set!\n"); }
if( !Duration.size() ) { fprintf(stderr,"WARNING: Duration not set!\n"); }
if( !UnitsPerSecond.size() ) { fprintf(stderr,"WARNING: Timescale not set!\n"); }
if( sttsvide.size() == 0 ) {
fprintf(stderr,"WARNING: No video stts available!\n");
} else { WriteSTTS( 1 ); }
if( sttssoun.size() == 0 ) {
fprintf(stderr,"WARNING: No sound stts available!\n");
} else { WriteSTTS( 2 ); }
if( stscvide.size() == 0 ) {
fprintf(stderr,"WARNING: No video stsc available!\n");
} else { WriteSTSC( 1 ); }
if( stscsoun.size() == 0 ) {
fprintf(stderr,"WARNING: No sound stsc available!\n");
} else { WriteSTSC( 2 ); }
stsd_vide->WriteContent( );
stco_vide->WriteContent( );
stsc_vide->WriteContent( );
stts_vide->WriteContent( );
stbl_vide->WriteContent( );
dref_vide->WriteContent( );
dinf_vide->WriteContent( );
minf_vide->WriteContent( );
mdia_vide->WriteContent( );
stsd_soun->WriteContent( );
stco_soun->WriteContent( );
stsc_soun->WriteContent( );
stts_soun->WriteContent( );
stbl_soun->WriteContent( );
dref_soun->WriteContent( );
dinf_soun->WriteContent( );
minf_soun->WriteContent( );
mdia_soun->WriteContent( );
trak_vide->WriteContent( );
trak_soun->WriteContent( );
mvex->WriteContent( );
moov->WriteContent( );
amhp->WriteContent( );
rtmp->WriteContent( );
afrt->WriteContent( );
asrt->WriteContent( );
abst->WriteContent( );
trun_soun->WriteContent( );
traf_soun->WriteContent( );
trun_vide->WriteContent( );
traf_vide->WriteContent( );
moof->WriteContent( );
}
bool Interface::AllBoxesExist() {
return ( ftyp && moov && mvhd && trak_vide && tkhd_vide && mdia_vide && mdhd_vide && hdlr_vide &&
minf_vide && vmhd_vide && dinf_vide && dref_vide && url_vide && stbl_vide && stts_vide && stsc_vide &&
stco_vide && stsd_vide && avcC_vide && trak_soun && tkhd_soun && mdia_soun && mdhd_soun && hdlr_soun &&
minf_soun && smhd_soun && dinf_soun && dref_soun && url_soun && stbl_soun && stts_soun && stsc_soun &&
stco_soun && stsd_soun && esds_soun && rtmp && amhp && mvex && trex_vide && trex_soun && afrt && asrt
&& abst && moof && mfhd && traf_vide && tfhd_vide && trun_vide && traf_soun && tfhd_soun && trun_soun );
}
void Interface::SetWidth( uint16_t NewWidth ) {
if( Width != NewWidth ) {
Width = NewWidth;
avcC_vide->SetWidth( Width );
tkhd_vide->SetWidth( Width );
}
}
void Interface::SetHeight( uint16_t NewHeight ) {
if( Height != NewHeight ) {
Height = NewHeight;
avcC_vide->SetHeight( Height );
tkhd_vide->SetHeight( Height );
}
}
void Interface::SetDurationTime( uint32_t NewDuration, uint32_t Track ) {
if( Duration.size() < Track ) { Duration.resize(Track+1); }
if( Duration[Track] != NewDuration ) {
Duration[Track] = NewDuration;
switch( Track ) {
case 0:
mvhd->SetDurationTime( Duration[Track] );
break;
case 1:
mdhd_vide->SetDurationTime( Duration[Track] );
tkhd_vide->SetDurationTime( Duration[Track] );
break;
case 2:
mdhd_soun->SetDurationTime( Duration[Track] );
tkhd_soun->SetDurationTime( Duration[Track] );
break;
default:
fprintf( stderr, "WARNING, Setting Duration for track %d does have any effect\n", Track );
break;
}
}
}
void Interface::SetTimeScale( uint32_t NewUnitsPerSecond, uint32_t Track ) {
if( UnitsPerSecond.size() < Track ) { UnitsPerSecond.resize(Track+1); }
if( UnitsPerSecond[Track] != NewUnitsPerSecond ) {
UnitsPerSecond[Track] = NewUnitsPerSecond;
switch(Track) {
case 0:
mvhd->SetTimeScale( UnitsPerSecond[Track] );
break;
case 1:
mdhd_vide->SetTimeScale( UnitsPerSecond[Track] );
break;
case 2:
mdhd_soun->SetTimeScale( UnitsPerSecond[Track] );
break;
default:
fprintf( stderr, "WARNING, Setting Timescale for track %d does have any effect\n", Track );
break;
}
}
}
void Interface::SetStaticDefaults() {
// 'vide' = 0x76696465
hdlr_vide->SetHandlerType( 0x76696465 );
hdlr_vide->SetName( "Video Track" );
// 'soun' = 0x736F756E
hdlr_soun->SetHandlerType( 0x736F756E );
hdlr_vide->SetName( "Audio Track" );
// Set Track ID's
tkhd_vide->SetTrackID( 1 );
tkhd_soun->SetTrackID( 2 );
trex_vide->SetTrackID( 1 );
trex_soun->SetTrackID( 2 );
// Set amhp entry
amhp->AddEntry( 1, 0, 0 );
}
void Interface::AddSTTSEntry( uint32_t SampleCount, uint32_t SampleDelta, uint32_t Track ) {
stts_record temp;
temp.SampleCount = SampleCount;
temp.SampleDelta = SampleDelta;
switch(Track) {
case 1:
sttsvide.push_back(temp);
break;
case 2:
sttssoun.push_back(temp);
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STTS not added\n", Track );
break;
}
}
void Interface::EmptySTTS( uint32_t Track ) {
switch(Track) {
case 1:
sttsvide.clear();
break;
case 2:
sttssoun.clear();
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STTS not cleared\n", Track );
break;
}
}
void Interface::WriteSTTS( uint32_t Track ) {
switch( Track ) {
case 1:
for( int i = sttsvide.size() -1; i > 0; i -- ) {
stts_vide->AddEntry(sttsvide[i].SampleCount,sttsvide[i].SampleDelta,i);
}
break;
case 2:
for( int i = sttssoun.size() -1; i > 0; i -- ) {
stts_soun->AddEntry(sttssoun[i].SampleCount,sttssoun[i].SampleDelta,i);
}
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STTS not written\n", Track );
break;
}
}
void Interface::AddSTSCEntry( uint32_t FirstChunk, uint32_t SamplesPerChunk, uint32_t Track ) {
stsc_record temp;
temp.FirstChunk = FirstChunk;
temp.SamplesPerChunk = SamplesPerChunk;
temp.SampleDescIndex = 1;
switch(Track) {
case 1:
stscvide.push_back(temp);
break;
case 2:
stscsoun.push_back(temp);
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STSC not added\n", Track );
break;
}
}
void Interface::EmptySTSC( uint32_t Track ) {
switch(Track) {
case 1:
stscvide.clear();
break;
case 2:
stscsoun.clear();
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STSC not cleared\n", Track );
break;
}
}
void Interface::WriteSTSC( uint32_t Track ) {
switch( Track ) {
case 1:
for( int i = stscvide.size() -1; i > 0; i -- ) {
stsc_vide->AddEntry(stscvide[i].FirstChunk,stscvide[i].SamplesPerChunk,1,i);
}
break;
case 2:
for( int i = stscsoun.size() -1; i > 0; i -- ) {
stsc_soun->AddEntry(stscsoun[i].FirstChunk,stscsoun[i].SamplesPerChunk,1,i);
}
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, STSC not written\n", Track );
break;
}
}
void Interface::SetOffsets( std::vector<uint32_t> NewOffsets, uint32_t Track ) {
switch( Track ) {
case 1:
stco_vide->SetOffsets( NewOffsets );
break;
case 2:
stco_soun->SetOffsets( NewOffsets );
break;
default:
fprintf( stderr, "WARNING: Track %d does not exist, Offsets not written\n", Track );
break;
}
}
std::string Interface::GenerateLiveBootstrap( uint32_t CurMediaTime ) {
//SetUpAFRT
afrt->SetUpdate(false);
afrt->SetTimeScale( 1000 );
afrt->AddQualityEntry( "" );
afrt->AddFragmentRunEntry( 1, 0, 0, 2 );
afrt->WriteContent( );
//SetUpASRT
asrt->SetUpdate(false);
asrt->AddQualityEntry( "" );
asrt->AddSegmentRunEntry( 1, 0 );
asrt->WriteContent( );
//SetUpABST
abst->SetBootstrapVersion( 1 );
abst->SetProfile( 0 );
abst->SetLive( true );
abst->SetUpdate( false );
abst->SetTimeScale( 1000 );
abst->SetMediaTime( CurMediaTime );
abst->SetSMPTE( 0 );
abst->SetMovieIdentifier( "" );
abst->SetDRM( "" );
abst->SetMetaData( "" );
abst->AddServerEntry( "" );
abst->AddQualityEntry( "" );
abst->WriteContent( );
std::string Result;
Result.append( (char*)abst->GetBox( )->GetBoxedData( ), (int)abst->GetBox( )->GetBoxedDataSize( ) );
return Result;
}
std::string Interface::mdatFold(std::string data){
static Box_mdat * mdat = new Box_mdat;
std::string Result;
mdat->SetContent((uint8_t*)data.c_str(), data.size());
Result.append((char*)mdat->GetBox()->GetBoxedData(), (int)mdat->GetBox()->GetBoxedDataSize());
return Result;
}

13
util/MP4/main.cpp Normal file
View file

@ -0,0 +1,13 @@
#include <iostream>
#include "interface.h"
int main( ) {
std::cout << "Creating Interface\n";
Interface * file = new Interface();
std::cout << "Interface created, start linking them\n";
file->link();
std::cout << "Linking finished, deleting boxes\n";
delete file;
std::cout << "Interface deleted\n";
return 0;
}