From 7b6eb6ad26f909f49b69a1d028605d009aee0fd8 Mon Sep 17 00:00:00 2001 From: Oswald de Bruin Date: Fri, 3 May 2013 13:42:13 +0200 Subject: [PATCH] Added Meta and Edit list boxes --- lib/mp4.cpp | 167 +++++++++++++++++++++++++++++++++++++++++++++++++--- lib/mp4.h | 30 +++++++++- 2 files changed, 188 insertions(+), 9 deletions(-) diff --git a/lib/mp4.cpp b/lib/mp4.cpp index b32efba2..6cfef87c 100644 --- a/lib/mp4.cpp +++ b/lib/mp4.cpp @@ -256,6 +256,12 @@ namespace MP4 { case 0x73747373: return ((STSS*)this)->toPrettyString(indent); break; + case 0x6D657461: + return ((META*)this)->toPrettyString(indent); + break; + case 0x656C7374: + return ((ELST*)this)->toPrettyString(indent); + break; case 0x75647461: return ((UDTA*)this)->toPrettyString(indent); break; @@ -565,6 +571,14 @@ namespace MP4 { uint32_t fullBox::getFlags(){ return getInt24(1); } + + std::string fullBox::toPrettyString(uint32_t indent){ + std::stringstream r; + r << std::string(indent + 1, ' ') << "Version: " << (int)getVersion() << std::endl; + r << std::string(indent + 1, ' ') << "Flags: " << getFlags() << std::endl; + return r.str(); + } + uint32_t containerBox::getContentCount(){ int res = 0; int tempLoc = 0; @@ -575,13 +589,6 @@ namespace MP4 { return res; } - std::string fullBox::toPrettyString(uint32_t indent){ - std::stringstream r; - r << std::string(indent + 1, ' ') << "Version: " << (int)getVersion() << std::endl; - r << std::string(indent + 1, ' ') << "Flags: " << getFlags() << std::endl; - return r.str(); - } - void containerBox::setContent(Box & newContent, uint32_t no){ int tempLoc = 0; int contentCount = getContentCount(); @@ -627,6 +634,63 @@ namespace MP4 { } return r.str(); } + + uint32_t containerFullBox::getContentCount(){ + int res = 0; + int tempLoc = 4; + while (tempLoc < boxedSize() - 8){ + res++; + tempLoc += getBoxLen(tempLoc); + } + return res; + } + + void containerFullBox::setContent(Box & newContent, uint32_t no){ + int tempLoc = 4; + 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 & containerFullBox::getContent(uint32_t no){ + static Box ret = Box((char*)"\000\000\000\010erro", false); + if (no > getContentCount()){ + return ret; + } + int i = 0; + int tempLoc = 4; + while (i < no){ + tempLoc += getBoxLen(tempLoc); + i++; + } + return getBox(tempLoc); + } + + std::string containerFullBox::toPrettyCFBString(uint32_t indent, std::string boxName){ + std::stringstream r; + r << std::string(indent, ' ') << boxName <<" (" << boxedSize() << ")" << std::endl; + r << fullBox::toPrettyString(indent); + Box curBox; + int tempLoc = 4; + 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); @@ -4051,7 +4115,7 @@ namespace MP4 { getInt32(4); } - void STSS::setSampleNumber(uint32 newVal, uint32_t index){ + void STSS::setSampleNumber(uint32_t newVal, uint32_t index){ if (index+1 > getEntryCount()){ setEntryCount(index); } @@ -4076,6 +4140,93 @@ namespace MP4 { return r.str(); } + META::META(){ + memcpy(data + 4, "meta", 4); + } + + std::string META::toPrettyString(uint32_t indent){ + return toPrettyCFBString(indent, "[meta] Meta Box"); + } + + ELST::ELST(){ + memcpy(data + 4, "elst", 4); + } + + void ELST::setSegmentDuration(uint64_t newVal){ + if (getVersion() == 1){ + setInt64(newVal, 4); + }else{ + setInt32(newVal, 4); + } + } + + uint64_t ELST::getSegmentDuration(){ + if (getVersion() == 1){ + return getInt64(4); + }else{ + return getInt32(4); + } + } + + void ELST::setMediaTime(uint64_t newVal){ + if (getVersion() == 1){ + setInt64(newVal, 12); + }else{ + setInt32(newVal, 8); + } + } + + uint64_t ELST::getMediaTime(){ + if (getVersion() == 1){ + return getInt64(12); + }else{ + return getInt32(8); + } + } + + void ELST::setMediaRateInteger(uint16_t newVal){ + if (getVersion() == 1){ + setInt16(newVal, 20); + }else{ + setInt16(newVal, 12); + } + } + + uint16_t ELST::getMediaRateInteger(){ + if (getVersion() == 1){ + return getInt16(20); + }else{ + return getInt16(12); + } + } + + void ELST::setMediaRateFraction(uint16_t newVal){ + if (getVersion() == 1){ + setInt16(newVal, 22); + }else{ + setInt16(newVal, 14); + } + } + + uint16_t ELST::getMediaRateFraction(){ + if (getVersion() == 1){ + return getInt16(22); + }else{ + return getInt16(14); + } + } + + std::string ELST::toPrettyString(uint32_t indent){ + std::stringstream r; + r << std::string(indent, ' ') << "[elst] Edit List Box (" << boxedSize() << ")" << std::endl; + r << fullBox::toPrettyString(indent); + r << std::string(indent + 1, ' ') << "SegmentDuration: " << getSegmentDuration() << std::endl; + r << std::string(indent + 1, ' ') << "MediaTime: " << getMediaTime() << std::endl; + r << std::string(indent + 1, ' ') << "MediaRateInteger: " << getMediaRateInteger() << std::endl; + r << std::string(indent + 1, ' ') << "MediaRateFraction: " << getMediaRateFraction() << 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; diff --git a/lib/mp4.h b/lib/mp4.h index 094f6d15..c69150fb 100644 --- a/lib/mp4.h +++ b/lib/mp4.h @@ -74,6 +74,14 @@ namespace MP4 { std::string toPrettyString(uint32_t indent = 0); std::string toPrettyContainerString(uint32_t indent, std::string boxName); }; + + class containerFullBox: public fullBox{ + public: + uint32_t getContentCount(); + void setContent(Box & newContent, uint32_t no); + Box & getContent(uint32_t no); + std::string toPrettyCFBString(uint32_t indent, std::string boxName); + }; struct afrt_runtable{ uint32_t firstFragment; @@ -803,10 +811,30 @@ namespace MP4 { STSS(); void setEntryCount(uint32_t newVal); uint32_t getEntryCount(); - void setSampleNumber(uint32 newVal, uint32_t index); + void setSampleNumber(uint32_t newVal, uint32_t index); uint32_t getSampleNumber(uint32_t index); std::string toPrettyString(uint32_t indent = 0); }; + + class META: public containerFullBox{ + public: + META(); + std::string toPrettyString(uint32_t indent = 0); + }; + + class ELST: public fullBox{ + public: + ELST(); + void setSegmentDuration(uint64_t newVal); + uint64_t getSegmentDuration(); + void setMediaTime(uint64_t newVal); + uint64_t getMediaTime(); + void setMediaRateInteger(uint16_t newVal); + uint16_t getMediaRateInteger(); + void setMediaRateFraction(uint16_t newVal); + uint16_t getMediaRateFraction(); + std::string toPrettyString(uint32_t indent = 0); + }; class UUID: public Box{ public: