MP4 Generic library cleanups, shorthands and fixes.

This commit is contained in:
Thulinma 2014-02-13 00:30:36 +01:00
parent e8f973b2e7
commit abdedba32c
3 changed files with 116 additions and 133 deletions

View file

@ -56,7 +56,7 @@ namespace MP4 {
char * data; ///< Holds the data of this box char * data; ///< Holds the data of this box
unsigned int data_size; ///< Currently reserved size unsigned int data_size; ///< Currently reserved size
bool managed; ///< If false, will not attempt to resize/free the data pointer. bool managed; ///< If false, will not attempt to resize/free the data pointer.
int payloadOffset; ///<The offset of the payload with regards to the data unsigned int payloadOffset; ///<The offset of the payload with regards to the data
}; };
//Box Class //Box Class

View file

@ -899,49 +899,68 @@ namespace MP4{
FTYP::FTYP(){ FTYP::FTYP(){
memcpy(data + 4, "ftyp", 4); memcpy(data + 4, "ftyp", 4);
setMajorBrand(0); setMajorBrand("mp41");
setMinorVersion(0); setMinorVersion("Mist");
setCompatibleBrands("isom",0);
setCompatibleBrands("iso2",1);
setCompatibleBrands("avc1",2);
setCompatibleBrands("mp41",3);
} }
void FTYP::setMajorBrand(uint32_t newMajorBrand){ void FTYP::setMajorBrand(const char * newMajorBrand){
setInt32(newMajorBrand, 0); if (payloadOffset + 3 >= boxedSize()){
if ( !reserve(payloadOffset, 0, 4)){
return;
}
}
memcpy(data + payloadOffset, newMajorBrand, 4);
} }
uint32_t FTYP::getMajorBrand(){ std::string FTYP::getMajorBrand(){
return getInt32(0); return std::string(data + payloadOffset, 4);
} }
void FTYP::setMinorVersion(uint32_t newMinorVersion){ void FTYP::setMinorVersion(const char * newMinorVersion){
setInt32(newMinorVersion, 4); if (payloadOffset + 7 >= boxedSize()){
if ( !reserve(payloadOffset+4, 0, 4)){
return;
}
}
memcpy(data + payloadOffset + 4, newMinorVersion, 4);
} }
uint32_t FTYP::getMinorVersion(){ std::string FTYP::getMinorVersion(){
return getInt32(4); return std::string(data+payloadOffset+4, 4);
} }
uint32_t FTYP::getCompatibleBrandsCount(){ size_t FTYP::getCompatibleBrandsCount(){
return (payloadSize() - 8) / 4; return (payloadSize() - 8) / 4;
} }
void FTYP::setCompatibleBrands(uint32_t newCompatibleBrand, size_t index){ void FTYP::setCompatibleBrands(const char * newCompatibleBrand, size_t index){
setInt32(newCompatibleBrand, 8 + (index * 4)); if (payloadOffset + 8+index*4 + 3 >= boxedSize()){
if ( !reserve(payloadOffset+8+index*4, 0, 4)){
return;
}
}
memcpy(data + payloadOffset+8+index*4, newCompatibleBrand, 4);
} }
uint32_t FTYP::getCompatibleBrands(size_t index){ std::string FTYP::getCompatibleBrands(size_t index){
if (index >= getCompatibleBrandsCount()){ if (index >= getCompatibleBrandsCount()){
return 0; return "";
} }
return getInt32(8 + (index * 4)); return std::string(data+payloadOffset+8 + (index * 4), 4);
} }
std::string FTYP::toPrettyString(uint32_t indent){ std::string FTYP::toPrettyString(uint32_t indent){
std::stringstream r; std::stringstream r;
r << std::string(indent, ' ') << "[ftyp] File Type (" << boxedSize() << ")" << std::endl; r << std::string(indent, ' ') << "[ftyp] File Type (" << boxedSize() << ")" << std::endl;
r << std::string(indent + 1, ' ') << "MajorBrand: 0x" << std::hex << getMajorBrand() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "MajorBrand: " << getMajorBrand() << std::endl;
r << std::string(indent + 1, ' ') << "MinorVersion: " << getMinorVersion() << std::endl; r << std::string(indent + 1, ' ') << "MinorVersion: " << getMinorVersion() << std::endl;
r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl; r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl;
for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++){ for (unsigned int i = 0; i < getCompatibleBrandsCount(); i++){
r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: 0x" << std::hex << getCompatibleBrands(i) << std::dec << std::endl; r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: " << getCompatibleBrands(i) << std::endl;
} }
return r.str(); return r.str();
} }
@ -1048,33 +1067,25 @@ namespace MP4{
return r.str(); return r.str();
} }
HDLR::HDLR(){ HDLR::HDLR(std::string & type, std::string name){
memcpy(data + 4, "hdlr", 4); memcpy(data + 4, "hdlr", 4);
setName(""); //reserve an entire box, except for the string part at the end
if (!reserve(0, 8, 32)){
return;//on fail, cancel all the things
}
memset(data+payloadOffset, 0, 24);//set all bytes (32 - 8) to zeroes
if (type == "video"){setHandlerType("vide");}
if (type == "audio"){setHandlerType("soun");}
setName(name);
} }
void HDLR::setSize(uint32_t newSize){ void HDLR::setHandlerType(const char * newHandlerType){
setInt32(newSize,0); memcpy(data+payloadOffset+8, newHandlerType, 4);
} }
uint32_t HDLR::getSize(){ std::string HDLR::getHandlerType(){
return getInt32(0); return std::string(data+payloadOffset+8, 4);
}
void HDLR::setPreDefined(uint32_t newPreDefined){
setInt32(newPreDefined,4);
}
uint32_t HDLR::getPreDefined(){
return getInt32(4);
}
void HDLR::setHandlerType(uint32_t newHandlerType){
setInt32(newHandlerType, 8);
}
uint32_t HDLR::getHandlerType(){
return getInt32(8);
} }
void HDLR::setName(std::string newName){ void HDLR::setName(std::string newName){
@ -1088,10 +1099,7 @@ namespace MP4{
std::string HDLR::toPrettyString(uint32_t indent){ std::string HDLR::toPrettyString(uint32_t indent){
std::stringstream r; std::stringstream r;
r << std::string(indent, ' ') << "[hdlr] Handler Reference (" << boxedSize() << ")" << std::endl; r << std::string(indent, ' ') << "[hdlr] Handler Reference (" << boxedSize() << ")" << std::endl;
r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl; r << std::string(indent + 1, ' ') << "Handler Type: " << getHandlerType() << std::endl;
r << std::string(indent + 1, ' ') << "HandlerType: " <<
(char)((getHandlerType() & 0xFF000000) >> 24) << (char)((getHandlerType() & 0x00FF0000) >> 16) <<
(char)((getHandlerType() & 0x0000FF00) >> 8) << (char)(getHandlerType() & 0x000000FF) << std::endl;
r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl; r << std::string(indent + 1, ' ') << "Name: " << getName() << std::endl;
return r.str(); return r.str();
} }
@ -1304,11 +1312,14 @@ namespace MP4{
return r.str(); return r.str();
} }
DREF::DREF(char v, uint32_t f){ DREF::DREF(){
memcpy(data + 4, "dref", 4); memcpy(data + 4, "dref", 4);
setVersion(v); setVersion(0);
setFlags(f); setFlags(0);
setInt32(0,4); setInt32(0,4);
URL urlBox;
urlBox.setFlags(1);
setDataEntry(urlBox, 0);
} }
uint32_t DREF::getEntryCount(){ uint32_t DREF::getEntryCount(){
@ -1359,44 +1370,24 @@ namespace MP4{
return r.str(); return r.str();
} }
MVHD::MVHD(char v, uint32_t f){
memcpy(data + 4, "mvhd", 4);
setVersion(v);
setFlags(f);
setCreationTime(0);
setModificationTime(0);
setTimeScale(1000);
setDuration(0);
setRate(0x00010000);
setVolume(0x0100);
setMatrix(0x40000000,0);
setMatrix(0x00010000,4);
setMatrix(0x00010000,8);
setTrackID(1);
}
MVHD::MVHD(long long unsigned int duration){ MVHD::MVHD(long long unsigned int duration){
//memcpy(data + 4, "mvhd", 4);
//char temp[] = {00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x03, 0xE8, 0x10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 40, 00, 00, 00};
//char temp[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x3d, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
//setString(temp, 0x4F, 0);
//setDuration(duration);
memcpy(data + 4, "mvhd", 4); memcpy(data + 4, "mvhd", 4);
setVersion(0);
setFlags(0);
setTrackID(1);
setTimeScale(1000);
setRate(0x00010000); //reserve an entire version 0 box
setVolume(0x0100); if (!reserve(0, 8, 108)){
setMatrix(0x40000000,0); return;//on fail, cancel all the things
}
memset(data+payloadOffset, 0, 100);//set all bytes (108 - 8) to zeroes
setTimeScale(1000);//we always use milliseconds
setDuration(duration);//in ms
setRate(0x00010000);//playback rate 1.0X
setVolume(0x0100);//volume 1.0X
setMatrix(0x00010000,0);
setMatrix(0x00010000,4); setMatrix(0x00010000,4);
setMatrix(0x00010000,8); setMatrix(0x40000000,8);
setTimeScale(1000); setTrackID(0xFFFFFFFF);//empty track numbers is unknown
setRate(0x10000);
setDuration(duration);
} }
void MVHD::setCreationTime(uint64_t newCreationTime){ void MVHD::setCreationTime(uint64_t newCreationTime){
@ -1764,23 +1755,26 @@ namespace MP4{
return r.str(); return r.str();
} }
TKHD::TKHD(char v, uint32_t f){ TKHD::TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height){
memcpy(data + 4, "tkhd", 4); memcpy(data + 4, "tkhd", 4);
setVersion(v);
setFlags(f); //reserve an entire version 0 box
setCreationTime(0); if (!reserve(0, 8, 92)){
setModificationTime(0); return;//on fail, cancel all the things
setTrackID(0); }
setDuration(0); memset(data+payloadOffset, 0, 84);//set all bytes (92 - 8) to zeroes
setLayer(0);
setAlternateGroup(0); setFlags(15);//ENABLED | IN_MOVIE | IN_PREVIEW | IN_POSTER
setVolume(0x0100); setTrackID(trackId);
setDuration(duration);
if (width == 0 || height == 0){
setVolume(0x0100);
}
setMatrix(0x00010000,0); setMatrix(0x00010000,0);
setMatrix(0x00010000,4); setMatrix(0x00010000,4);
//fills automatically with zero's
setMatrix(0x40000000,8); setMatrix(0x40000000,8);
setWidth(0); setWidth(width << 16);
setHeight(0); setHeight(height << 16);
} }
void TKHD::setCreationTime(uint64_t newCreationTime){ void TKHD::setCreationTime(uint64_t newCreationTime){
@ -1817,7 +1811,7 @@ namespace MP4{
void TKHD::setTrackID(uint32_t newTrackID){ void TKHD::setTrackID(uint32_t newTrackID){
if (getVersion() == 0){ if (getVersion() == 0){
setInt32((uint32_t) newTrackID, 12); setInt32(newTrackID, 12);
}else{ }else{
setInt32(newTrackID, 20); setInt32(newTrackID, 20);
} }
@ -1902,9 +1896,9 @@ namespace MP4{
void TKHD::setMatrix(int32_t newMatrix, size_t index){ void TKHD::setMatrix(int32_t newMatrix, size_t index){
int offset = 0; int offset = 0;
if (getVersion() == 0){ if (getVersion() == 0){
offset = 36 + 2 + 2; offset = 40;
}else{ }else{
offset = 48 + 2 + 2; offset = 52;
} }
setInt32(newMatrix, offset + index * 4); setInt32(newMatrix, offset + index * 4);
} }
@ -1912,9 +1906,9 @@ namespace MP4{
int32_t TKHD::getMatrix(size_t index){ int32_t TKHD::getMatrix(size_t index){
int offset = 0; int offset = 0;
if (getVersion() == 0){ if (getVersion() == 0){
offset = 36 + 2 + 2; offset = 40;
}else{ }else{
offset = 48 + 2 + 2; offset = 52;
} }
return getInt32(offset + index * 4); return getInt32(offset + index * 4);
} }
@ -1975,20 +1969,16 @@ namespace MP4{
return r.str(); return r.str();
} }
MDHD::MDHD(char v, uint32_t f){ MDHD::MDHD(uint64_t duration){
memcpy(data + 4, "mdhd", 4); memcpy(data + 4, "mdhd", 4);
setVersion(v); //reserve an entire version 0 box
setFlags(f); if (!reserve(0, 8, 32)){
setCreationTime(0); return;//on fail, cancel all the things
setModificationTime(0);
setTimeScale(1000);
setDuration(0);
setLanguage(0);
if (v==0){
setInt16(0,22);
}else{
setInt16(0,34);
} }
memset(data+payloadOffset, 0, 24);//set all bytes (32 - 8) to zeroes
setTimeScale(1000);
setDuration(duration);
} }
void MDHD::setCreationTime(uint64_t newCreationTime){ void MDHD::setCreationTime(uint64_t newCreationTime){

View file

@ -184,13 +184,13 @@ namespace MP4{
class FTYP: public Box{ class FTYP: public Box{
public: public:
FTYP(); FTYP();
void setMajorBrand(uint32_t newMajorBrand); void setMajorBrand(const char * newMajorBrand);
uint32_t getMajorBrand(); std::string getMajorBrand();
void setMinorVersion(uint32_t newMinorVersion); void setMinorVersion(const char * newMinorVersion);
uint32_t getMinorVersion(); std::string getMinorVersion();
uint32_t getCompatibleBrandsCount(); size_t getCompatibleBrandsCount();
void setCompatibleBrands(uint32_t newCompatibleBrand, size_t index); void setCompatibleBrands(const char * newCompatibleBrand, size_t index);
uint32_t getCompatibleBrands(size_t index); std::string getCompatibleBrands(size_t index);
std::string toPrettyString(uint32_t indent = 0); std::string toPrettyString(uint32_t indent = 0);
}; };
@ -256,13 +256,9 @@ namespace MP4{
class HDLR: public Box{ class HDLR: public Box{
public: public:
HDLR(); HDLR(std::string & type, std::string name);
void setSize(uint32_t newSize); void setHandlerType(const char * newHandlerType);
uint32_t getSize(); std::string getHandlerType();
void setPreDefined(uint32_t newPreDefined);
uint32_t getPreDefined();
void setHandlerType(uint32_t newHandlerType);
uint32_t getHandlerType();
void setName(std::string newName); void setName(std::string newName);
std::string getName(); std::string getName();
std::string toPrettyString(uint32_t indent = 0); std::string toPrettyString(uint32_t indent = 0);
@ -340,7 +336,7 @@ namespace MP4{
class DREF: public fullBox{ class DREF: public fullBox{
public: public:
DREF(char v = 1, uint32_t = 0); DREF();
uint32_t getEntryCount(); uint32_t getEntryCount();
void setDataEntry(fullBox & newDataEntry, size_t index); void setDataEntry(fullBox & newDataEntry, size_t index);
Box & getDataEntry(size_t index); Box & getDataEntry(size_t index);
@ -349,7 +345,6 @@ namespace MP4{
class MVHD: public fullBox{ class MVHD: public fullBox{
public: public:
MVHD(char v = 1, uint32_t f = 0);
MVHD(long long unsigned int duration); MVHD(long long unsigned int duration);
void setCreationTime(uint64_t newCreationTime); void setCreationTime(uint64_t newCreationTime);
uint64_t getCreationTime(); uint64_t getCreationTime();
@ -363,7 +358,6 @@ namespace MP4{
uint32_t getRate(); uint32_t getRate();
void setVolume(uint16_t newVolume); void setVolume(uint16_t newVolume);
uint16_t getVolume(); uint16_t getVolume();
///\todo fix default values
uint32_t getMatrixCount(); uint32_t getMatrixCount();
void setMatrix(int32_t newMatrix, size_t index); void setMatrix(int32_t newMatrix, size_t index);
int32_t getMatrix(size_t index); int32_t getMatrix(size_t index);
@ -401,7 +395,7 @@ namespace MP4{
class TKHD: public fullBox{ class TKHD: public fullBox{
public: public:
TKHD(char v = 1, uint32_t f = 0); TKHD(uint32_t trackId, uint64_t duration, uint32_t width, uint32_t height);
void setCreationTime(uint64_t newCreationTime); void setCreationTime(uint64_t newCreationTime);
uint64_t getCreationTime(); uint64_t getCreationTime();
void setModificationTime(uint64_t newModificationTime); void setModificationTime(uint64_t newModificationTime);
@ -418,7 +412,6 @@ namespace MP4{
void setVolume(uint16_t newVolume); void setVolume(uint16_t newVolume);
uint16_t getVolume(); uint16_t getVolume();
///\todo fix default values
uint32_t getMatrixCount(); uint32_t getMatrixCount();
void setMatrix(int32_t newMatrix, size_t index); void setMatrix(int32_t newMatrix, size_t index);
int32_t getMatrix(size_t index); int32_t getMatrix(size_t index);
@ -432,7 +425,7 @@ namespace MP4{
class MDHD: public fullBox{ class MDHD: public fullBox{
public: public:
MDHD(char v = 1, uint32_t f = 0); MDHD(uint64_t duration);
void setCreationTime(uint64_t newCreationTime); void setCreationTime(uint64_t newCreationTime);
uint64_t getCreationTime(); uint64_t getCreationTime();
void setModificationTime(uint64_t newModificationTime); void setModificationTime(uint64_t newModificationTime);