Bijna klaar!
This commit is contained in:
parent
a30f63ab5a
commit
183827ae9f
42 changed files with 3198 additions and 0 deletions
18
util/MP4/Makefile
Normal file
18
util/MP4/Makefile
Normal 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
150
util/MP4/box.cpp
Normal 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
218
util/MP4/box_abst.cpp
Normal 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
75
util/MP4/box_afra.cpp
Normal 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
100
util/MP4/box_afrt.cpp
Normal 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
63
util/MP4/box_amhp.cpp
Normal 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
81
util/MP4/box_asrt.cpp
Normal 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
86
util/MP4/box_avcC.cpp
Normal 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
43
util/MP4/box_dinf.cpp
Normal 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
58
util/MP4/box_dref.cpp
Normal 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
55
util/MP4/box_esds.cpp
Normal 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
39
util/MP4/box_ftyp.cpp
Normal 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
59
util/MP4/box_hdlr.cpp
Normal 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
57
util/MP4/box_hmhd.cpp
Normal 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
37
util/MP4/box_includes.h
Normal 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
29
util/MP4/box_mdat.cpp
Normal 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
88
util/MP4/box_mdhd.cpp
Normal 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
51
util/MP4/box_mdia.cpp
Normal 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
39
util/MP4/box_mfhd.cpp
Normal 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
51
util/MP4/box_minf.cpp
Normal 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
51
util/MP4/box_moof.cpp
Normal 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
51
util/MP4/box_moov.cpp
Normal 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
51
util/MP4/box_mvex.cpp
Normal 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
113
util/MP4/box_mvhd.cpp
Normal 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
28
util/MP4/box_nmhd.cpp
Normal 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
89
util/MP4/box_rtmp.cpp
Normal 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
29
util/MP4/box_smhd.cpp
Normal 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
51
util/MP4/box_stbl.cpp
Normal 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
58
util/MP4/box_stco.cpp
Normal 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
63
util/MP4/box_stsc.cpp
Normal 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
59
util/MP4/box_stsd.cpp
Normal 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
60
util/MP4/box_stts.cpp
Normal 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
88
util/MP4/box_tfhd.cpp
Normal 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
117
util/MP4/box_tkhd.cpp
Normal 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
51
util/MP4/box_traf.cpp
Normal 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
51
util/MP4/box_trak.cpp
Normal 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
59
util/MP4/box_trex.cpp
Normal 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
68
util/MP4/box_trun.cpp
Normal 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
23
util/MP4/box_url.cpp
Normal 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
45
util/MP4/box_vmhd.cpp
Normal 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
583
util/MP4/interface.cpp
Normal 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
13
util/MP4/main.cpp
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue