First container boxes implemented for MP4.
Also my first fixes for boxes.
This commit is contained in:
parent
6f7b300bf5
commit
c6eca9b990
2 changed files with 270 additions and 56 deletions
251
lib/mp4.cpp
251
lib/mp4.cpp
|
@ -154,6 +154,21 @@ namespace MP4 {
|
|||
case 0x73647470:
|
||||
return ((SDTP*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x66747970:
|
||||
return ((FTYP*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D6F6F76:
|
||||
return ((MOOV*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D766578:
|
||||
return ((MVEX*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x74726578:
|
||||
return ((TREX*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x6D667261:
|
||||
return ((MFRA*)this)->toPrettyString(indent);
|
||||
break;
|
||||
case 0x75756964:
|
||||
return ((UUID*)this)->toPrettyString(indent);
|
||||
break;
|
||||
|
@ -445,6 +460,62 @@ namespace MP4 {
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t containerBox::getContentCount(){
|
||||
int res = 0;
|
||||
int tempLoc = 0;
|
||||
while (tempLoc < boxedSize() - 8){
|
||||
res++;
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void containerBox::setContent(Box & newContent, uint32_t no){
|
||||
int tempLoc = 0;
|
||||
int contentCount = getContentCount();
|
||||
for (int i = 0; i < no; i++){
|
||||
if (i < contentCount){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}else{
|
||||
if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){
|
||||
return;
|
||||
};
|
||||
memset(data + tempLoc, 0, (no - contentCount) * 8);
|
||||
tempLoc += (no - contentCount) * 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setBox(newContent, tempLoc);
|
||||
}
|
||||
|
||||
Box & containerBox::getContent(uint32_t no){
|
||||
static Box ret = Box((char*)"\000\000\000\010erro", false);
|
||||
if (no > getContentCount()){
|
||||
return ret;
|
||||
}
|
||||
int i = 0;
|
||||
int tempLoc = 0;
|
||||
while (i < no){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
i++;
|
||||
}
|
||||
return getBox(tempLoc);
|
||||
}
|
||||
|
||||
std::string containerBox::toPrettyContainerString(int indent, std::string boxName){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << boxName <<" (" << boxedSize() << ")" << std::endl;
|
||||
Box curBox;
|
||||
int tempLoc = 0;
|
||||
int contentCount = getContentCount();
|
||||
for (int i = 0; i < contentCount; i++){
|
||||
curBox = getContent(i);
|
||||
r << curBox.toPrettyString(indent + 1);
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
|
||||
ABST::ABST(){
|
||||
memcpy(data + 4, "abst", 4);
|
||||
setVersion(0);
|
||||
|
@ -1192,60 +1263,8 @@ namespace MP4 {
|
|||
memcpy(data + 4, "moof", 4);
|
||||
}
|
||||
|
||||
uint32_t MOOF::getContentCount(){
|
||||
int res = 0;
|
||||
int tempLoc = 0;
|
||||
while (tempLoc < boxedSize() - 8){
|
||||
res++;
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void MOOF::setContent(Box & newContent, uint32_t no){
|
||||
int tempLoc = 0;
|
||||
int contentCount = getContentCount();
|
||||
for (int i = 0; i < no; i++){
|
||||
if (i < contentCount){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}else{
|
||||
if ( !reserve(tempLoc, 0, (no - contentCount) * 8)){
|
||||
return;
|
||||
};
|
||||
memset(data + tempLoc, 0, (no - contentCount) * 8);
|
||||
tempLoc += (no - contentCount) * 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setBox(newContent, tempLoc);
|
||||
}
|
||||
|
||||
Box & MOOF::getContent(uint32_t no){
|
||||
static Box ret = Box((char*)"\000\000\000\010erro", false);
|
||||
if (no > getContentCount()){
|
||||
return ret;
|
||||
}
|
||||
int i = 0;
|
||||
int tempLoc = 0;
|
||||
while (i < no){
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
i++;
|
||||
}
|
||||
return getBox(tempLoc);
|
||||
}
|
||||
|
||||
std::string MOOF::toPrettyString(int indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[moof] Movie Fragment Box (" << boxedSize() << ")" << std::endl;
|
||||
Box curBox;
|
||||
int tempLoc = 0;
|
||||
int contentCount = getContentCount();
|
||||
for (int i = 0; i < contentCount; i++){
|
||||
curBox = getContent(i);
|
||||
r << curBox.toPrettyString(indent + 1);
|
||||
tempLoc += getBoxLen(tempLoc);
|
||||
}
|
||||
return r.str();
|
||||
return toPrettyContainerString(indent, std::string("[moof] Movie Fragment Box"));
|
||||
}
|
||||
|
||||
TRAF::TRAF(){
|
||||
|
@ -2145,6 +2164,124 @@ namespace MP4 {
|
|||
return r.str();
|
||||
}
|
||||
|
||||
FTYP::FTYP(){
|
||||
memcpy(data + 4, "ftyp", 4);
|
||||
}
|
||||
|
||||
void FTYP::setMajorBrand(uint32_t newMajorBrand){
|
||||
setInt32(newMajorBrand, 0);
|
||||
}
|
||||
|
||||
uint32_t FTYP::getMajorBrand(){
|
||||
return getInt32(0);
|
||||
}
|
||||
|
||||
void FTYP::setMinorVersion(uint32_t newMinorVersion){
|
||||
setInt32(newMinorVersion, 4);
|
||||
}
|
||||
|
||||
uint32_t FTYP::getMinorVersion(){
|
||||
return getInt32(4);
|
||||
}
|
||||
|
||||
uint32_t FTYP::getCompatibleBrandsCount(){
|
||||
return (payloadSize() - 8) / 4;
|
||||
}
|
||||
|
||||
void FTYP::setCompatibleBrands(uint32_t newCompatibleBrand, size_t index){
|
||||
setInt32(newCompatibleBrand, 8 + (index * 4));
|
||||
}
|
||||
|
||||
uint32_t FTYP::getCompatibleBrands(size_t index){
|
||||
if (index >= getCompatibleBrandsCount()){
|
||||
return 0;
|
||||
}
|
||||
return getInt32(8 + (index * 4));
|
||||
}
|
||||
|
||||
std::string FTYP::toPrettyString(int indent){
|
||||
std::stringstream r;
|
||||
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, ' ') << "MinorVersion: " << getMinorVersion() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "CompatibleBrands (" << getCompatibleBrandsCount() << "):" << std::endl;
|
||||
for (int i = 0; i < getCompatibleBrandsCount(); i++){
|
||||
r << std::string(indent + 2, ' ') << "[" << i << "] CompatibleBrand: 0x" << std::hex << getCompatibleBrands(i) << std::dec << std::endl;
|
||||
}
|
||||
return r.str();
|
||||
}
|
||||
|
||||
MOOV::MOOV(){
|
||||
memcpy(data + 4, "moov", 4);
|
||||
}
|
||||
|
||||
std::string MOOV::toPrettyString(int indent){
|
||||
return toPrettyContainerString(indent, std::string("[moov] Movie Box"));
|
||||
}
|
||||
|
||||
MVEX::MVEX(){
|
||||
memcpy(data + 4, "mvex", 4);
|
||||
}
|
||||
|
||||
std::string MVEX::toPrettyString(int indent){
|
||||
return toPrettyContainerString(indent, std::string("[mvex] Movie Extends Header Box"));
|
||||
}
|
||||
|
||||
TREX::TREX(){
|
||||
memcpy(data + 4, "ftyp", 4);
|
||||
}
|
||||
|
||||
void TREX::setTrackID(uint32_t newTrackID){
|
||||
setInt32(newTrackID, 0);
|
||||
}
|
||||
|
||||
uint32_t TREX::getTrackID(){
|
||||
return getInt32(0);
|
||||
}
|
||||
|
||||
void TREX::setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex){
|
||||
setInt32(newDefaultSampleDescriptionIndex,4);
|
||||
}
|
||||
|
||||
uint32_t TREX::getDefaultSampleDescriptionIndex(){
|
||||
return getInt32(4);
|
||||
}
|
||||
|
||||
void TREX::setDefaultSampleDuration(uint32_t newDefaultSampleDuration){
|
||||
setInt32(newDefaultSampleDuration,8);
|
||||
}
|
||||
|
||||
uint32_t TREX::getDefaultSampleDuration(){
|
||||
getInt32(8);
|
||||
}
|
||||
|
||||
void TREX::setDefaultSampleSize(uint32_t newDefaultSampleSize){
|
||||
setInt32(newDefaultSampleSize,12);
|
||||
}
|
||||
|
||||
uint32_t TREX::getDefaultSampleSize(){
|
||||
getInt32(12);
|
||||
}
|
||||
|
||||
void TREX::setDefaultSampleFlags(uint32_t newDefaultSampleFlags){
|
||||
setInt32(newDefaultSampleFlags,16);
|
||||
}
|
||||
|
||||
uint32_t TREX::getDefaultSampleFlags(){
|
||||
getInt32(16);
|
||||
}
|
||||
|
||||
std::string TREX::toPrettyString(int indent){
|
||||
std::stringstream r;
|
||||
r << std::string(indent, ' ') << "[trex] Track Extends (" << boxedSize() << ")" << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "TrackID: " << getTrackID() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "DefaultSampleDescriptionIndex : " << getDefaultSampleDescriptionIndex() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "DefaultSampleDuration : " << getDefaultSampleDuration() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "DefaultSampleSize : " << getDefaultSampleSize() << std::endl;
|
||||
r << std::string(indent + 1, ' ') << "DefaultSampleFlags : " << getDefaultSampleFlags() << std::endl;
|
||||
return r.str();
|
||||
}
|
||||
|
||||
static char c2hex(int c){
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
|
@ -2152,6 +2289,14 @@ namespace MP4 {
|
|||
return 0;
|
||||
}
|
||||
|
||||
MFRA::MFRA(){
|
||||
memcpy(data + 4, "mfra", 4);
|
||||
}
|
||||
|
||||
std::string MFRA::toPrettyString(int indent){
|
||||
return toPrettyContainerString(indent, std::string("[mfra] Movie Fragment Random Acces Box"));
|
||||
}
|
||||
|
||||
UUID::UUID(){
|
||||
memcpy(data + 4, "uuid", 4);
|
||||
setInt64(0, 0);
|
||||
|
|
75
lib/mp4.h
75
lib/mp4.h
|
@ -55,7 +55,17 @@ namespace MP4 {
|
|||
int payloadOffset; ///<The offset of the payload with regards to the data
|
||||
};
|
||||
//Box Class
|
||||
|
||||
|
||||
class containerBox: public Box{
|
||||
public:
|
||||
//containerBox();
|
||||
uint32_t getContentCount();
|
||||
void setContent(Box & newContent, uint32_t no);
|
||||
Box & getContent(uint32_t no);
|
||||
std::string toPrettyString(int indent = 0);
|
||||
std::string toPrettyContainerString(int indent, std::string boxName);
|
||||
};
|
||||
|
||||
struct afrt_runtable{
|
||||
uint32_t firstFragment;
|
||||
uint64_t firstTimestamp;
|
||||
|
@ -160,13 +170,19 @@ namespace MP4 {
|
|||
};
|
||||
//MFHD Box
|
||||
|
||||
class MOOF: public Box{
|
||||
/*class MOOF: public Box{
|
||||
public:
|
||||
MOOF();
|
||||
uint32_t getContentCount();
|
||||
void setContent(Box & newContent, uint32_t no);
|
||||
Box & getContent(uint32_t no);
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};*/
|
||||
|
||||
class MOOF: public containerBox{
|
||||
public:
|
||||
MOOF();
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
//MOOF Box
|
||||
|
||||
|
@ -319,7 +335,60 @@ namespace MP4 {
|
|||
uint32_t getValue(size_t index);
|
||||
std::string toPrettyString(uint32_t indent = 0);
|
||||
};
|
||||
|
||||
|
||||
class FTYP: public Box{
|
||||
public:
|
||||
FTYP();
|
||||
void setMajorBrand(uint32_t newMajorBrand);
|
||||
uint32_t getMajorBrand();
|
||||
void setMinorVersion(uint32_t newMinorVersion);
|
||||
uint32_t getMinorVersion();
|
||||
uint32_t getCompatibleBrandsCount();
|
||||
void setCompatibleBrands(uint32_t newCompatibleBrand, size_t index);
|
||||
uint32_t getCompatibleBrands(size_t index);
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
|
||||
class MOOV: public containerBox{
|
||||
public:
|
||||
MOOV();
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
|
||||
class MVEX: public containerBox{
|
||||
public:
|
||||
MVEX();
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
|
||||
class TREX: public Box{
|
||||
public:
|
||||
TREX();
|
||||
void setTrackID(uint32_t newTrackID);
|
||||
uint32_t getTrackID();
|
||||
void setDefaultSampleDescriptionIndex(uint32_t newDefaultSampleDescriptionIndex);
|
||||
uint32_t getDefaultSampleDescriptionIndex();
|
||||
void setDefaultSampleDuration(uint32_t newDefaultSampleDuration);
|
||||
uint32_t getDefaultSampleDuration();
|
||||
void setDefaultSampleSize(uint32_t newDefaultSampleSize);
|
||||
uint32_t getDefaultSampleSize();
|
||||
void setDefaultSampleFlags(uint32_t newDefaultSampleFlags);
|
||||
uint32_t getDefaultSampleFlags();
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
|
||||
|
||||
class MFRA: public containerBox{
|
||||
public:
|
||||
MFRA();
|
||||
std::string toPrettyString(int indent = 0);
|
||||
};
|
||||
|
||||
/*class MDAT: public Box{
|
||||
public:
|
||||
MDAT();
|
||||
};*/
|
||||
|
||||
class UUID: public Box{
|
||||
public:
|
||||
UUID();
|
||||
|
|
Loading…
Add table
Reference in a new issue