From a1ed3a8465b5e089894b31e6a2a0a0daa9e5781d Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 7 Mar 2013 20:08:22 +0100 Subject: [PATCH] Implemented SDTP, UUID and UUID_TrackFragmentReference boxes in MP4 lib. --- lib/mp4.cpp | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++- lib/mp4.h | 27 ++++++++ 2 files changed, 222 insertions(+), 1 deletion(-) diff --git a/lib/mp4.cpp b/lib/mp4.cpp index 0095868a..dec687d2 100644 --- a/lib/mp4.cpp +++ b/lib/mp4.cpp @@ -151,10 +151,19 @@ namespace MP4 { case 0x61766343: return ((AVCC*)this)->toPrettyString(indent); break; + case 0x73647470: + return ((SDTP*)this)->toPrettyString(indent); + break; + case 0x75756964: + return ((UUID*)this)->toPrettyString(indent); + break; default: break; } - return std::string(indent, ' ') + "Unimplemented pretty-printing for box " + std::string(data + 4, 4) + "\n"; + std::string retval = std::string(indent, ' ') + "Unimplemented pretty-printing for box " + std::string(data + 4, 4) + "\n"; + /// \todo Implement hexdump for unimplemented boxes? + //retval += + return retval; } /// Sets the 8 bits integer at the given index. @@ -2080,4 +2089,189 @@ namespace MP4 { uint32_t SDTP::getValue(size_t index){ getInt8(index); } + + std::string SDTP::toPrettyString(uint32_t indent){ + std::stringstream r; + r << std::string(indent, ' ') << "[sdtp] Sample Dependancy Type (" << boxedSize() << ")" << std::endl; + r << std::string(indent + 1, ' ') << "Samples: " << (boxedSize() - 12) << std::endl; + for (size_t i = 1; i <= boxedSize() - 12; ++i){ + uint32_t val = getValue(i+3); + r << std::string(indent + 2, ' ') << "[" << i << "] = "; + switch (val & 3){ + case 0: + r << " "; + break; + case 1: + r << "Redundant, "; + break; + case 2: + r << "Not redundant, "; + break; + case 3: + r << "Error, "; + break; + } + switch (val & 12){ + case 0: + r << " "; + break; + case 4: + r << "Not disposable, "; + break; + case 8: + r << "Disposable, "; + break; + case 12: + r << "Error, "; + break; + } + switch (val & 48){ + case 0: + r << " "; + break; + case 16: + r << "IFrame, "; + break; + case 32: + r << "Not IFrame, "; + break; + case 48: + r << "Error, "; + break; + } + r << "(" << val << ")" << 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; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return 0; + } + + UUID::UUID(){ + memcpy(data + 4, "uuid", 4); + setInt64(0, 0); + setInt64(0, 8); + } + + std::string UUID::getUUID(){ + std::stringstream r; + r << std::hex; + for (int i = 0; i < 16; ++i){ + if (i == 4 || i == 6 || i == 8 || i == 10){ + r << "-"; + } + r << std::setfill('0') << std::setw(2) << std::right << (int)(data[8+i]); + } + return r.str(); + } + + void UUID::setUUID(const std::string & uuid_string){ + //reset UUID to zero + for (int i = 0; i < 4; ++i){ + ((uint32_t*)(data+8))[i] = 0; + } + //set the UUID from the string, char by char + int i = 0; + for (size_t j = 0; j < uuid_string.size(); ++j){ + if (uuid_string[j] == '-'){ + continue; + } + data[8+i/2] |= (c2hex(uuid_string[j]) << (4-(4*(i%2)))); + ++i; + } + } + + void UUID::setUUID(const char * raw_uuid){ + memcpy(data+8, raw_uuid, 16); + } + + std::string UUID::toPrettyString(uint32_t indent){ + std::string UUID = getUUID(); + if (UUID == "d4807ef2-ca39-4695-8e54-26cb9e46a79f"){ + return ((UUID_TrackFragmentReference*)this)->toPrettyString(indent); + } + std::stringstream r; + r << std::string(indent, ' ') << "[uuid] Extension box (" << boxedSize() << ")" << std::endl; + r << std::string(indent + 1, ' ') << "UUID: " << UUID << std::endl; + r << std::string(indent + 1, ' ') << "Unknown UUID - ignoring contents." << std::endl; + return r.str(); + } + + UUID_TrackFragmentReference::UUID_TrackFragmentReference(){ + setUUID((std::string)"d4807ef2-ca39-4695-8e54-26cb9e46a79f"); + } + + void UUID_TrackFragmentReference::setVersion(uint32_t newVersion){ + setInt8(newVersion, 16); + } + + uint32_t UUID_TrackFragmentReference::getVersion(){ + return getInt8(16); + } + + void UUID_TrackFragmentReference::setFlags(uint32_t newFlags){ + setInt24(newFlags, 17); + } + + uint32_t UUID_TrackFragmentReference::getFlags(){ + return getInt24(17); + } + + void UUID_TrackFragmentReference::setFragmentCount(uint32_t newCount){ + setInt8(newCount, 20); + } + + uint32_t UUID_TrackFragmentReference::getFragmentCount(){ + return getInt8(20); + } + + void UUID_TrackFragmentReference::setTime(size_t num, uint64_t newTime){ + if (getVersion() == 0){ + setInt32(newTime, 21+(num*8)); + }else{ + setInt64(newTime, 21+(num*16)); + } + } + + uint64_t UUID_TrackFragmentReference::getTime(size_t num){ + if (getVersion() == 0){ + return getInt32(21+(num*8)); + }else{ + return getInt64(21+(num*16)); + } + } + + void UUID_TrackFragmentReference::setDuration(size_t num, uint64_t newDuration){ + if (getVersion() == 0){ + setInt32(newDuration, 21+(num*8)+4); + }else{ + setInt64(newDuration, 21+(num*16)+8); + } + } + + uint64_t UUID_TrackFragmentReference::getDuration(size_t num){ + if (getVersion() == 0){ + return getInt32(21+(num*8)+4); + }else{ + return getInt64(21+(num*16)+8); + } + } + + std::string UUID_TrackFragmentReference::toPrettyString(uint32_t indent){ + std::stringstream r; + r << std::string(indent, ' ') << "[d4807ef2-ca39-4695-8e54-26cb9e46a79f] Track Fragment Reference (" << boxedSize() << ")" << std::endl; + r << std::string(indent + 1, ' ') << "Version: " << getVersion() << std::endl; + r << std::string(indent + 1, ' ') << "Fragments: " << getFragmentCount() << std::endl; + int j = getFragmentCount(); + for (int i = 0; i < j; ++i){ + r << std::string(indent + 2, ' ') << "[" << i << "] Time = " << getTime(i) << ", Duration = " << getDuration(i) << std::endl; + } + return r.str(); + } + + } diff --git a/lib/mp4.h b/lib/mp4.h index 053b59e3..a7d8f80e 100644 --- a/lib/mp4.h +++ b/lib/mp4.h @@ -317,6 +317,33 @@ namespace MP4 { uint32_t getVersion(); void setValue(uint32_t newValue, size_t index); uint32_t getValue(size_t index); + std::string toPrettyString(uint32_t indent = 0); }; + + class UUID: public Box{ + public: + UUID(); + std::string getUUID(); + void setUUID(const std::string & uuid_string); + void setUUID(const char * raw_uuid); + std::string toPrettyString(uint32_t indent = 0); + }; + + class UUID_TrackFragmentReference: public UUID{ + public: + UUID_TrackFragmentReference(); + void setVersion(uint32_t newVersion); + uint32_t getVersion(); + void setFlags(uint32_t newFlags); + uint32_t getFlags(); + void setFragmentCount(uint32_t newCount); + uint32_t getFragmentCount(); + void setTime(size_t num, uint64_t newTime); + uint64_t getTime(size_t num); + void setDuration(size_t num, uint64_t newDuration); + uint64_t getDuration(size_t num); + std::string toPrettyString(uint32_t indent = 0); + }; + }