From 29669f24c4758c6df6d3a134399841a4bb7fffc2 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Tue, 31 Jan 2017 14:48:49 +0100 Subject: [PATCH] MP4 speed optimize --- lib/mp4.cpp | 34 ++++++++++++--------------- lib/mp4.h | 3 ++- lib/mp4_generic.cpp | 5 ++-- lib/mp4_generic.h | 2 +- src/output/output_progressive_mp4.cpp | 2 +- 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/lib/mp4.cpp b/lib/mp4.cpp index 64c4a039..4c06aff7 100644 --- a/lib/mp4.cpp +++ b/lib/mp4.cpp @@ -84,25 +84,21 @@ namespace MP4 { return std::string(retVal + 4, 4); } - ///\todo make good working calcBoxSize with size and payloadoffset calculation - unsigned long int calcBoxSize(char readVal[16]) { - return (unsigned int)ntohl(((int *)readVal)[0]); + /// Checks box size, offset-aware + uint64_t calcBoxSize(const char * p){ + uint64_t r = ntohl(((int *)p)[0]); + if (r == 1){ + return (((uint64_t)ntohl(((int *)p)[2])) << 32) | ntohl(((int *)p)[3]); + } + return r; } bool skipBox(FILE * newData) { char readVal[16]; long long unsigned int pos = ftell(newData); - if (fread(readVal, 4, 1, newData)) { + if (fread(readVal, 16, 1, newData)) { uint64_t size = calcBoxSize(readVal); - if (size == 1) { - if (fread(readVal + 4, 12, 1, newData)) { - size = 0 + ntohl(((int *)readVal)[2]); - size <<= 32; - size += ntohl(((int *)readVal)[3]); - } else { - return false; - } - } else if (size == 0) { + if (size == 0) { fseek(newData, 0, SEEK_END); return true; } @@ -120,9 +116,9 @@ namespace MP4 { bool Box::read(FILE * newData) { char readVal[16]; long long unsigned int pos = ftell(newData); - if (fread(readVal, 4, 1, newData)) { + if (fread(readVal, 16, 1, newData)) { payloadOffset = 8; - uint64_t size = calcBoxSize(readVal); + uint64_t size = ntohl(((int *)readVal)[0]); if (size == 1) { if (fread(readVal + 4, 12, 1, newData)) { size = 0 + ntohl(((int *)readVal)[2]); @@ -182,7 +178,7 @@ namespace MP4 { /// Returns the total boxed size of this box, including the header. uint64_t Box::boxedSize() { if (payloadOffset == 16) { - return ((uint64_t)ntohl(((int *)data)[2]) << 32) + ntohl(((int *)data)[3]); + return ((uint64_t)ntohl(((int *)data)[2]) << 32) | ntohl(((int *)data)[3]); } return ntohl(((int *)data)[0]); } @@ -621,7 +617,7 @@ namespace MP4 { if ((index + payloadOffset + 8) > boxedSize()) { return 0; } - return getBox(index).boxedSize(); + return calcBoxSize(data + index + payloadOffset); } /// Replaces the existing box at the given index by the new box newEntry. @@ -732,9 +728,9 @@ namespace MP4 { setBox(newContent, tempLoc); } - Box & containerBox::getContent(uint32_t no) { + Box & containerBox::getContent(uint32_t no, bool unsafe) { static Box ret = Box((char *)"\000\000\000\010erro", false); - if (no > getContentCount()) { + if (!unsafe && no > getContentCount()) { return ret; } unsigned int i = 0; diff --git a/lib/mp4.h b/lib/mp4.h index adf3863e..4b18fc57 100644 --- a/lib/mp4.h +++ b/lib/mp4.h @@ -17,6 +17,7 @@ namespace MP4 { std::string readBoxType(FILE * newData); bool skipBox(FILE * newData); + uint64_t calcBoxSize(const char * p); class Box { @@ -81,7 +82,7 @@ namespace MP4 { containerBox(); uint32_t getContentCount(); void setContent(Box & newContent, uint32_t no); - Box & getContent(uint32_t no); + Box & getContent(uint32_t no, bool unsafe = false); std::string toPrettyString(uint32_t indent = 0); }; diff --git a/lib/mp4_generic.cpp b/lib/mp4_generic.cpp index e37c6748..878b9280 100644 --- a/lib/mp4_generic.cpp +++ b/lib/mp4_generic.cpp @@ -58,9 +58,10 @@ namespace MP4 { setBox(newContent, tempLoc); } - Box & TRAF::getContent(uint32_t no) { + /// Gets a reference to the given box number. If unsafe, doesn't check boundaries (getContentCount check skipped). + Box & TRAF::getContent(uint32_t no, bool unsafe) { static Box ret = Box((char *)"\000\000\000\010erro", false); - if (no > getContentCount()) { + if (!unsafe && no > getContentCount()) { return ret; } unsigned int i = 0; diff --git a/lib/mp4_generic.h b/lib/mp4_generic.h index a31e749e..c89bb7ac 100644 --- a/lib/mp4_generic.h +++ b/lib/mp4_generic.h @@ -21,7 +21,7 @@ namespace MP4 { TRAF(); uint32_t getContentCount(); void setContent(Box & newContent, uint32_t no); - Box & getContent(uint32_t no); + Box & getContent(uint32_t no, bool unsafe = false); std::string toPrettyString(uint32_t indent = 0); }; //TRAF Box diff --git a/src/output/output_progressive_mp4.cpp b/src/output/output_progressive_mp4.cpp index c3ec0945..80e91809 100644 --- a/src/output/output_progressive_mp4.cpp +++ b/src/output/output_progressive_mp4.cpp @@ -542,7 +542,7 @@ namespace Mist { char * dataPointer = 0; unsigned int len = 0; thisPacket.getString("data", dataPointer, len); - if ((unsigned long)thisPacket.getTrackId() != sortSet.begin()->trackID || thisPacket.getTime() != sortSet.begin()->time){ + if ((unsigned long)thisPacket.getTrackId() != sortSet.begin()->trackID || thisPacket.getTime() != sortSet.begin()->time || len != sortSet.begin()->size) { if (thisPacket.getTime() > sortSet.begin()->time || (unsigned long)thisPacket.getTrackId() > sortSet.begin()->trackID) { if (perfect){ DEBUG_MSG(DLVL_WARN, "Warning: input is inconsistent. Expected %lu:%llu but got %ld:%llu - cancelling playback", sortSet.begin()->trackID, sortSet.begin()->time, thisPacket.getTrackId(), thisPacket.getTime());