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
		Add a link
		
	
		Reference in a new issue
	
	 Ozzay
						Ozzay