diff --git a/MP4/Makefile b/MP4/Makefile index 37626f38..d7a716ef 100644 --- a/MP4/Makefile +++ b/MP4/Makefile @@ -1,4 +1,4 @@ -SRC = box_avcC.cpp box.cpp box_dinf.cpp box_dref.cpp box_esds.cpp box_ftyp.cpp box_hdlr.cpp box_hmhd.cpp box_mdhd.cpp box_mdia.cpp box_minf.cpp box_moov.cpp box_mvhd.cpp box_nmhd.cpp box_smhd.cpp box_stbl.cpp box_stco.cpp box_stsc.cpp box_stsd.cpp box_stts.cpp box_tkhd.cpp box_trak.cpp box_url.cpp box_vmhd.cpp main.cpp interface.cpp box_mdat.cpp box_rtmp.cpp box_amhp.cpp box_mvex.cpp box_trex.cpp box_afra.cpp box_abst.cpp box_asrt.cpp +SRC = box_avcC.cpp box.cpp box_dinf.cpp box_dref.cpp box_esds.cpp box_ftyp.cpp box_hdlr.cpp box_hmhd.cpp box_mdhd.cpp box_mdia.cpp box_minf.cpp box_moov.cpp box_mvhd.cpp box_nmhd.cpp box_smhd.cpp box_stbl.cpp box_stco.cpp box_stsc.cpp box_stsd.cpp box_stts.cpp box_tkhd.cpp box_trak.cpp box_url.cpp box_vmhd.cpp main.cpp interface.cpp box_mdat.cpp box_rtmp.cpp box_amhp.cpp box_mvex.cpp box_trex.cpp box_afra.cpp box_abst.cpp box_asrt.cpp box_afrt.cpp OBJ = $(SRC:.cpp=.o) OUT = Boxtest INCLUDES = diff --git a/MP4/box_afrt.cpp b/MP4/box_afrt.cpp new file mode 100644 index 00000000..b42c1195 --- /dev/null +++ b/MP4/box_afrt.cpp @@ -0,0 +1,72 @@ +#include "box_afrt.h" + +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))); +} diff --git a/MP4/box_afrt.h b/MP4/box_afrt.h new file mode 100644 index 00000000..215e7977 --- /dev/null +++ b/MP4/box_afrt.h @@ -0,0 +1,29 @@ +#include "box.h" +#include +#include + +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 QualitySegmentUrlModifiers; + std::vector FragmentRunEntryTable; + Box * Container; +};//Box_ftyp Class diff --git a/MP4/box_asrt.cpp b/MP4/box_asrt.cpp index cb777860..73f207ed 100644 --- a/MP4/box_asrt.cpp +++ b/MP4/box_asrt.cpp @@ -44,7 +44,7 @@ void Box_asrt::WriteContent( ) { serializedQualities += '\0'; } - uint32_t OffsetSegmentRunEntryCount = 8 + serializedQualities.size(); + 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); diff --git a/MP4/box_includes.h b/MP4/box_includes.h index 9b5f5bef..c466fb67 100644 --- a/MP4/box_includes.h +++ b/MP4/box_includes.h @@ -27,5 +27,6 @@ #include "box_mvex.h" #include "box_trex.h" #include "box_afra.h" -#include "box_asrt.h" #include "box_abst.h" +#include "box_asrt.h" +#include "box_afrt.h"