From 87d027817c924bbd7aa7a67cac47a61d74c4c71d Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 19 Dec 2013 13:36:48 +0100 Subject: [PATCH] Assorted fixes, improvements etc --- lib/dtsc.cpp | 15 ++++++++-- lib/dtscmeta.cpp | 7 +++-- lib/json.h | 34 ++++++++++++++++++++++ lib/mp4.cpp | 76 +++++++++++++++++++++++++++++++----------------- lib/mp4.h | 6 ++-- 5 files changed, 103 insertions(+), 35 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index 8a9951fe..4ad6fa82 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -224,6 +224,9 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ while (buffers.count(newPos) > 0){ newPos.seekTime++; } + while (buffercount == 1 && buffers.size() > 0){ + cutOneBuffer(); + } buffers[newPos] = newPack; datapointertype = INVALID; std::string tmp = ""; @@ -262,9 +265,6 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ metadata.bufferWindow = buffertime; } - while (buffercount == 1 && buffers.size() > 1){ - cutOneBuffer(); - } } /// Deletes a the first part of the buffer, updating the keyframes list and metadata as required. @@ -922,6 +922,15 @@ bool DTSC::File::seek_bpos(int bpos){ return false; } +void DTSC::File::rewritePacket(std::string & newPacket, int bytePos){ + fseek(F, bytePos, SEEK_SET); + fwrite(newPacket.c_str(), newPacket.size(), 1, F); + fseek(F, 0, SEEK_END); + if (ftell(F) > endPos){ + endPos = ftell(F); + } +} + void DTSC::File::writePacket(std::string & newPacket){ fseek(F, 0, SEEK_END); fwrite(newPacket.c_str(), newPacket.size(), 1, F); //write contents diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index 108ea619..1c2b2957 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -209,11 +209,11 @@ namespace DTSC { Track::Track(JSON::Value & trackRef){ if (trackRef.isMember("fragments") && trackRef["fragments"].isString()){ Fragment* tmp = (Fragment*)trackRef["fragments"].asString().data(); - fragments = std::deque(tmp,tmp + (trackRef["fragments"].asString().size() / 11)); + fragments = std::deque(tmp, tmp + (trackRef["fragments"].asString().size() / 11)); } if (trackRef.isMember("keys") && trackRef["keys"].isString()){ Key* tmp = (Key*)trackRef["keys"].asString().data(); - keys = std::deque(tmp,tmp + (trackRef["keys"].asString().size() / 16)); + keys = std::deque(tmp, tmp + (trackRef["keys"].asString().size() / 16)); } if (trackRef.isMember("parts") && trackRef["parts"].isString()){ Part* tmp = (Part*)trackRef["parts"].asString().data(); @@ -277,7 +277,7 @@ namespace DTSC { } keys.push_back(newKey); firstms = keys[0].getTime(); - if (!fragments.size() || pack["time"].asInt() - 10000 >= getKey(fragments.rbegin()->getNumber()).getTime()){ + if (!fragments.size() || pack["time"].asInt() - 5000 >= getKey(fragments.rbegin()->getNumber()).getTime()){ //new fragment Fragment newFrag; newFrag.setDuration(0); @@ -342,6 +342,7 @@ namespace DTSC { readOnlyMeta::readOnlyMeta(){ vod = false; live = false; + merged = false; moreheader = 0; merged = false; bufferWindow = 0; diff --git a/lib/json.h b/lib/json.h index 2f4db947..f8b56eac 100644 --- a/lib/json.h +++ b/lib/json.h @@ -140,4 +140,38 @@ namespace JSON { } } } + + template + std::string encodeVector4(T begin, T end){ + std::string result; + for( T it = begin; it != end; it++){ + long long int tmp = (*it); + while(tmp >= 0xFFFFFFFF){ + result += (char)0xFF; + result += (char)0xFF; + result += (char)0xFF; + result += (char)0xFF; + tmp -= 0xFFFFFFFF; + } + result += (char)((tmp & 0xFF000000) >> 24); + result += (char)((tmp & 0x00FF0000) >> 16); + result += (char)((tmp & 0x0000FF00) >> 8); + result += (char)((tmp & 0x000000FF)); + } + return result; + } + + template + void decodeVector4( std::string input, T & result ){ + result.clear(); + unsigned int tmp = 0; + for( int i = 0; i < input.size(); i += 4){ + unsigned int curLen = (input[i] << 24) + (input[i+1] << 16) + (input[i+2] << 8) + (input[i+3]); + tmp += curLen; + if (curLen != 0xFFFFFFFF){ + result.push_back(tmp); + tmp = 0; + } + } + } } diff --git a/lib/mp4.cpp b/lib/mp4.cpp index 2b7237ca..5a8cbb5d 100644 --- a/lib/mp4.cpp +++ b/lib/mp4.cpp @@ -244,7 +244,8 @@ namespace MP4 { case 0x73747364: return ((STSD*)this)->toPrettyString(indent); break; - case 0x6D703461: + case 0x6D703461://mp4a + case 0x656E6361://enca return ((MP4A*)this)->toPrettyString(indent); break; case 0x61616320: @@ -253,7 +254,8 @@ namespace MP4 { case 0x61766331: return ((AVC1*)this)->toPrettyString(indent); break; - case 0x68323634: + case 0x68323634://h264 + case 0x656E6376://encv return ((H264*)this)->toPrettyString(indent); break; case 0x65647473: @@ -493,7 +495,7 @@ namespace MP4 { /// Will attempt to resize if out of range. /// Returns an 8-byte error box if resizing failed. Box & Box::getBox(size_t index){ - static Box retbox; + static Box retbox = Box((char*)"\000\000\000\010erro", false); index += payloadOffset; if (index + 8 > boxedSize()){ if ( !reserve(index, 0, 8)){ @@ -510,7 +512,7 @@ namespace MP4 { /// Returns undefined values if there is no box at the given position. /// Returns 0 if out of range. size_t Box::getBoxLen(size_t index){ - if (index + payloadOffset + 8 > boxedSize()){ + if ((index + payloadOffset + 8) > boxedSize()){ return 0; } return getBox(index).boxedSize(); @@ -600,7 +602,7 @@ namespace MP4 { int tempLoc = 0; while (tempLoc < boxedSize() - 8){ res++; - tempLoc += getBoxLen(tempLoc); + tempLoc += Box(getBox(tempLoc).asBox(), false).boxedSize(); } return res; } @@ -640,13 +642,9 @@ namespace MP4 { std::string containerBox::toPrettyContainerString(uint32_t 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); + for (int i = 0; i < getContentCount(); i++){ + Box curBox = MP4::Box(getContent(i).asBox(), false); r << curBox.toPrettyString(indent + 1); - tempLoc += getBoxLen(tempLoc); } return r.str(); } @@ -1508,13 +1506,10 @@ namespace MP4 { std::string TRAF::toPrettyString(uint32_t indent){ std::stringstream r; r << std::string(indent, ' ') << "[traf] Track Fragment Box (" << boxedSize() << ")" << std::endl; - Box curBox; - int tempLoc = 0; int contentCount = getContentCount(); for (int i = 0; i < contentCount; i++){ - curBox = getContent(i); + Box curBox = Box(getContent(i).asBox(),false); r << curBox.toPrettyString(indent + 1); - tempLoc += curBox.boxedSize(); } return r.str(); } @@ -2274,6 +2269,25 @@ namespace MP4 { return r.str(); } + void AVCC::fromAnnexB(std::string annexBFormatted){ + ///\todo fix correct data :p + setVersion(0x01); + setProfile(0x4D); + setCompatibleProfiles(0x40); + setLevel(0x1F); + setSPSNumber(0xE1); + static char annexBHeader[] = {0x00,0x00,0x00,0x01}; + if (memcmp(annexBFormatted.c_str(), annexBHeader, 4)){ + return; + } + annexBFormatted.erase(0,4); + int separator = annexBFormatted.find(annexBHeader, 0, 4); + setSPS(annexBFormatted.substr(0,separator)); + setPPSNumber(0x01); + annexBFormatted.erase(0,separator+4); + setPPS(annexBFormatted); + } + void AVCC::setPayload(std::string newPayload){ if ( !reserve(0, payloadSize(), newPayload.size())){ std::cerr << "Cannot allocate enough memory for payload" << std::endl; @@ -2518,8 +2532,9 @@ namespace MP4 { r << std::string(indent + 1, ' ') << "ConfigDescriptorTypeLength: 0x" << std::hex << (int)getConfigDescriptorTypeLength() << std::dec << std::endl; r << std::string(indent + 1, ' ') << "ESHeaderStartCodes: 0x"; for (unsigned int i = 0; i> 16; } + + uint16_t AudioSampleEntry::toAACInit(){ + uint16_t result = 0; + result |= (2 & 0x1F) << 11; + result |= (getSampleRate() & 0x0F) << 7; + result |= (getChannelCount() & 0x0F) << 3; + return result; + } void AudioSampleEntry::setCodecBox(Box& newBox){ setBox(newBox, 28); @@ -4356,7 +4382,7 @@ namespace MP4 { r << std::string(indent + 1, ' ') << "SampleSize: " << getSampleSize() << std::endl; r << std::string(indent + 1, ' ') << "PreDefined: " << getPreDefined() << std::endl; r << std::string(indent + 1, ' ') << "SampleRate: " << getSampleRate() << std::endl; - r << getCodecBox().toPrettyString(indent + 1) << std::endl; + r << getCodecBox().toPrettyString(indent + 1); return r.str(); } @@ -4447,13 +4473,9 @@ namespace MP4 { r << std::string(indent, ' ') << "[stsd] Sample Description Box (" << boxedSize() << ")" << std::endl; r << fullBox::toPrettyString(indent); r << std::string(indent + 1, ' ') << "EntrySize: " << getEntryCount() << std::endl; - Box curBox; - int tempLoc = 0; - int contentCount = getEntryCount(); - for (int i = 0; i < contentCount; i++){ - curBox = getEntry(i); + for (int i = 0; i < getEntryCount(); i++){ + Box curBox = Box(getEntry(i).asBox(), false); r << curBox.toPrettyString(indent + 1); - tempLoc += getBoxLen(tempLoc); } return r.str(); } diff --git a/lib/mp4.h b/lib/mp4.h index 68dfeea0..0715171e 100644 --- a/lib/mp4.h +++ b/lib/mp4.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "json.h" #include "dtsc.h" @@ -256,7 +257,7 @@ namespace MP4 { uint32_t sampleDuration; uint32_t sampleSize; uint32_t sampleFlags; - uint32_t sampleOffset; + int32_t sampleOffset; }; enum trunflags{ trundataOffset = 0x00000001, @@ -378,6 +379,7 @@ namespace MP4 { uint32_t getPPSLen(); char* getPPS(); std::string asAnnexB(); + void fromAnnexB(std::string annexBFormatted); void setPayload(std::string newPayload); std::string toPrettyString(uint32_t indent = 0); }; @@ -869,6 +871,7 @@ namespace MP4 { uint16_t getPreDefined(); void setSampleRate(uint32_t newSampleRate); uint32_t getSampleRate(); + uint16_t toAACInit(); void setCodecBox(Box& newBox); Box & getCodecBox(); std::string toPrettyAudioString(uint32_t indent = 0, std::string name = ""); @@ -976,4 +979,3 @@ namespace MP4 { }; } -