diff --git a/src/analysers/dtsc_analyser.cpp b/src/analysers/dtsc_analyser.cpp index dc78a21d..61b9f5d6 100644 --- a/src/analysers/dtsc_analyser.cpp +++ b/src/analysers/dtsc_analyser.cpp @@ -38,11 +38,21 @@ namespace Analysers { long long unsigned int bfrm_min = 0xffffffff; long long unsigned int bfrm_max = 0; long long unsigned int bps = 0; + + std::set selector; + for (JSON::ObjIter trackIt = meta["tracks"].ObjBegin(); trackIt != meta["tracks"].ObjEnd(); trackIt++){ + selector.insert(trackIt->second["trackid"].asInt()); + } + F.selectTracks(selector); + + F.getMeta().null(); + + F.seek_time(0); F.seekNext(); - while ( !F.getJSON().isNull()){ - std::cout << F.getJSON().toPrettyString() << std::endl; + while (F.getJSON()){ nowpack = F.getJSON()["time"].asInt(); + std::cout << F.getJSON().toPrettyString() << std::endl; if (firstpack == 0){ firstpack = nowpack; } diff --git a/src/buffer/player.cpp b/src/buffer/player.cpp index e7093911..66b9bf3c 100644 --- a/src/buffer/player.cpp +++ b/src/buffer/player.cpp @@ -154,9 +154,7 @@ int main(int argc, char** argv){ json_sts["vod"]["meta"] = meta; for (JSON::ObjIter oIt = json_sts["vod"]["meta"]["tracks"].ObjBegin(); oIt != json_sts["vod"]["meta"]["tracks"].ObjEnd(); oIt++){ oIt->second.removeMember("init"); - oIt->second.removeMember("keytime"); - oIt->second.removeMember("keybpos"); - oIt->second.removeMember("keynum"); + oIt->second.removeMember("keys"); oIt->second.removeMember("frags"); } meta_sent = true; @@ -232,6 +230,7 @@ int main(int argc, char** argv){ playing = 0; } if (source.atKeyframe()){ + ///\todo Fix auto-delay on playing == -1. if (playing == -1 && meta["video"]["keyms"].asInt() > now - lastTime){ Util::sleep(meta["video"]["keyms"].asInt() - (now - lastTime)); } diff --git a/src/connectors/conn_http_smooth.cpp b/src/connectors/conn_http_smooth.cpp index 7d3cea3b..b7a13ddd 100644 --- a/src/connectors/conn_http_smooth.cpp +++ b/src/connectors/conn_http_smooth.cpp @@ -73,7 +73,7 @@ namespace Connector_HTTP { "Type=\"audio\" " "QualityLevels=\"" << allAudio.size() << "\" " "Name=\"audio\" " - "Chunks=\"" << allAudio.ObjBegin()->second["keytime"].size() << "\" " + "Chunks=\"" << allAudio.ObjBegin()->second["keys"].size() << "\" " "Url=\"Q({bitrate})/A({start time})\">\n"; int index = 1; for (JSON::ObjIter oIt = allAudio.ObjBegin(); oIt != allAudio.ObjEnd(); oIt++){ @@ -93,12 +93,12 @@ namespace Connector_HTTP { "FourCC=\"AACL\" />\n"; index++; } - for (unsigned int i = 0; i < allAudio.ObjBegin()->second["keylen"].size(); i++){ + for (JSON::ArrIter keyIt = allAudio.ObjBegin()->second["keys"].ArrBegin(); keyIt != allAudio.ObjBegin()->second["keys"].ArrEnd(); keyIt++){ Result << "second["keytime"][0u].asInt() * 10000 << "\" "; + if (keyIt == allAudio.ObjBegin()->second["keys"].ArrBegin()){ + Result << "t=\"" << allAudio.ObjBegin()->second["firstms"].asInt() * 10000 << "\" "; } - Result << "d=\"" << allAudio.ObjBegin()->second["keylen"][i].asInt() * 10000 << "\" />\n"; + Result << "d=\"" << (*keyIt)["len"].asInt() * 10000 << "\" />\n"; } Result << "\n"; } @@ -108,7 +108,7 @@ namespace Connector_HTTP { "Type=\"video\" " "QualityLevels=\"" << allVideo.size() << "\" " "Name=\"video\" " - "Chunks=\"" << allVideo.ObjBegin()->second["keytime"].size() << "\" " + "Chunks=\"" << allVideo.ObjBegin()->second["keys"].size() << "\" " "Url=\"Q({bitrate})/V({start time})\" " "MaxWidth=\"" << maxWidth << "\" " "MaxHeight=\"" << maxHeight << "\" " @@ -133,12 +133,12 @@ namespace Connector_HTTP { "FourCC=\"AVC1\" />\n"; index++; } - for (unsigned int i = 0; i < allVideo.ObjBegin()->second["keylen"].size(); i++){ + for (JSON::ArrIter keyIt = allVideo.ObjBegin()->second["keys"].ArrBegin(); keyIt != allVideo.ObjBegin()->second["keys"].ArrEnd(); keyIt++){ Result << "second["keytime"][i].asInt() * 10000 << "\" "; + if (keyIt == allVideo.ObjBegin()->second["keys"].ArrBegin()){ + Result << "t=\"" << allVideo.ObjBegin()->second["firstms"].asInt() * 10000 << "\" "; } - Result << "d=\"" << allVideo.ObjBegin()->second["keylen"][i].asInt() * 10000 << "\" />\n"; + Result << "d=\"" << (*keyIt)["len"].asInt() * 10000 << "\" />\n"; } Result << "\n"; } @@ -246,6 +246,7 @@ namespace Connector_HTTP { parseString = parseString.substr(parseString.find("(") + 1); requestedTime = atoll(parseString.substr(0, parseString.find(")")).c_str()); if (Strm.metadata.isMember("live")){ + ///\todo Fix this for live stuff int seekable = Strm.canSeekms(requestedTime / 10000); if (seekable == 0){ // iff the fragment in question is available, check if the next is available too @@ -277,12 +278,13 @@ namespace Connector_HTTP { } //Seek to the right place and send a play-once for a single fragment. std::stringstream sstream; + JSON::Value myRef; long long int selectedQuality = atoll(Quality.c_str()) / 8; if (wantsVideo){ //Select the correct track ID for (JSON::ObjIter vIt = allVideo.ObjBegin(); vIt != allVideo.ObjEnd(); vIt++){ if (vIt->second["bps"].asInt() == selectedQuality){ - sstream << "t " << vIt->second["trackid"].asInt() << "\n"; + myRef = vIt->second; } } } @@ -290,12 +292,103 @@ namespace Connector_HTTP { //Select the correct track ID for (JSON::ObjIter aIt = allAudio.ObjBegin(); aIt != allAudio.ObjEnd(); aIt++){ if (aIt->second["bps"].asInt() == selectedQuality){ - sstream << "t " << aIt->second["trackid"].asInt() << "\n"; + myRef = aIt->second; } } } + sstream << "t " << myRef["trackid"].asInt() << "\n"; sstream << "s " << (requestedTime / 10000) << "\no \n"; ss.SendNow(sstream.str().c_str()); + + HTTP_S.Clean(); + HTTP_S.SetHeader("Content-Type", "video/mp4"); + HTTP_S.SetBody(""); + + unsigned int myDuration; + + //Wrap everything in mp4 boxes + MP4::MFHD mfhd_box; + JSON::Value trackRef; + if (wantsVideo){ + trackRef = allVideo.ObjBegin()->second; + } + if (wantsAudio){ + trackRef = allAudio.ObjBegin()->second; + } + //Also obtain the associated keyframe; + JSON::Value keyObj; + for (JSON::ArrIter keyIt = trackRef["keys"].ArrBegin(); keyIt != trackRef["keys"].ArrEnd(); keyIt++){ + if ((*keyIt)["time"].asInt() >= (requestedTime / 10000)){ + keyObj = (*keyIt); + mfhd_box.setSequenceNumber((*keyIt)["num"].asInt()); + myDuration = (*keyIt)["len"].asInt() * 10000; + break; + } + } + + MP4::TFHD tfhd_box; + tfhd_box.setFlags(MP4::tfhdSampleFlag); + tfhd_box.setTrackID(1); + tfhd_box.setDefaultSampleFlags(0x000000C0 | MP4::noIPicture | MP4::noDisposable | MP4::noKeySample); + + MP4::TRUN trun_box; + trun_box.setFlags(MP4::trundataOffset | MP4::trunfirstSampleFlags | MP4::trunsampleDuration | MP4::trunsampleSize); + trun_box.setDataOffset(42); + trun_box.setFirstSampleFlags(0x00000040 | MP4::isIPicture | MP4::noDisposable | MP4::isKeySample); + for (int i = 0; i < keyObj["parts"].size(); i++){ + MP4::trunSampleInformation trunSample; + trunSample.sampleSize = keyObj["parts"][i].asInt(); + //Guesstimate sample duration. + trunSample.sampleDuration = ((double)(keyObj["len"].asInt() * 10000) / keyObj["parts"].size()); + trun_box.setSampleInformation(trunSample, i); + } + + MP4::SDTP sdtp_box; + sdtp_box.setVersion(0); + sdtp_box.setValue(0x24, 4); + for (int i = 1; i < keyObj["parts"].size(); i++){ + sdtp_box.setValue(0x14, 4 + i); + } + + MP4::TRAF traf_box; + traf_box.setContent(tfhd_box, 0); + traf_box.setContent(trun_box, 1); + traf_box.setContent(sdtp_box, 2); + + //If the stream is live, we want to have a fragref box if possible + if (Strm.metadata.isMember("live")){ + ///\todo Fix this for live + MP4::UUID_TrackFragmentReference fragref_box; + fragref_box.setVersion(1); + fragref_box.setFragmentCount(0); + int fragCount = 0; + for (int i = 0; i < Strm.metadata["keytime"].size(); i++){ + if (Strm.metadata["keytime"][i].asInt() > (requestedTime / 10000)){ + fragref_box.setTime(fragCount, Strm.metadata["keytime"][i].asInt() * 10000); + fragref_box.setDuration(fragCount, Strm.metadata["keylen"][i].asInt() * 10000); + fragref_box.setFragmentCount(++fragCount); + } + } + traf_box.setContent(fragref_box, 3); + } + + MP4::MOOF moof_box; + moof_box.setContent(mfhd_box, 0); + moof_box.setContent(traf_box, 1); + + //Setting the correct offsets. + trun_box.setDataOffset(moof_box.boxedSize() + 8); + traf_box.setContent(trun_box, 1); + moof_box.setContent(traf_box, 1); + + //Send the complete message + HTTP_S.SetHeader("Content-Length", keyObj["size"].asInt() + 8 + moof_box.boxedSize()); + conn.SendNow(HTTP_S.BuildResponse("200", "OK")); + conn.SendNow(moof_box.asBox(), moof_box.boxedSize()); + + unsigned long size = htonl(keyObj["size"].asInt() + 8); + conn.SendNow((char*) &size, 4); + conn.SendNow("mdat", 4); }else{ //We have a request for a Manifest, generate and send it. HTTP_S.Clean(); @@ -322,106 +415,10 @@ namespace Connector_HTTP { } if (ss.spool()){ while (Strm.parsePacket(ss.Received())){ - if (Strm.lastType() == DTSC::PAUSEMARK){ - //Send the current buffer - if (dataSize){ - HTTP_S.Clean(); - HTTP_S.SetHeader("Content-Type", "video/mp4"); - HTTP_S.SetBody(""); - - unsigned int myDuration; - - //Wrap everything in mp4 boxes - MP4::MFHD mfhd_box; - JSON::Value trackRef; - if (wantsVideo){ - trackRef = allVideo.ObjBegin()->second; - } - if (wantsAudio){ - trackRef = allAudio.ObjBegin()->second; - } - for (int i = 0; i < trackRef["keytime"].size(); i++){ - if (trackRef["keytime"][i].asInt() >= (requestedTime / 10000)){ - mfhd_box.setSequenceNumber(trackRef["keynum"][i].asInt()); - myDuration = trackRef["keylen"][i].asInt() * 10000; - break; - } - } - - MP4::TFHD tfhd_box; - tfhd_box.setFlags(MP4::tfhdSampleFlag); - tfhd_box.setTrackID(1); - tfhd_box.setDefaultSampleFlags(0x000000C0 | MP4::noIPicture | MP4::noDisposable | MP4::noKeySample); - - MP4::TRUN trun_box; - trun_box.setFlags(MP4::trundataOffset | MP4::trunfirstSampleFlags | MP4::trunsampleDuration | MP4::trunsampleSize); - trun_box.setDataOffset(42); - trun_box.setFirstSampleFlags(0x00000040 | MP4::isIPicture | MP4::noDisposable | MP4::isKeySample); - for (int i = 0; i < dataBuffer.size(); i++){ - MP4::trunSampleInformation trunSample; - trunSample.sampleSize = dataBuffer[i].size(); - trunSample.sampleDuration = (((double)myDuration / dataBuffer.size()) * i) - (((double)myDuration / dataBuffer.size()) * (i - 1)); - trun_box.setSampleInformation(trunSample, i); - } - - MP4::SDTP sdtp_box; - sdtp_box.setVersion(0); - sdtp_box.setValue(0x24, 4); - for (int i = 1; i < dataBuffer.size(); i++){ - sdtp_box.setValue(0x14, 4 + i); - } - - MP4::TRAF traf_box; - traf_box.setContent(tfhd_box, 0); - traf_box.setContent(trun_box, 1); - traf_box.setContent(sdtp_box, 2); - - //If the stream is live, we want to have a fragref box if possible - if (Strm.metadata.isMember("live")){ - MP4::UUID_TrackFragmentReference fragref_box; - fragref_box.setVersion(1); - fragref_box.setFragmentCount(0); - int fragCount = 0; - for (int i = 0; i < Strm.metadata["keytime"].size(); i++){ - if (Strm.metadata["keytime"][i].asInt() > (requestedTime / 10000)){ - fragref_box.setTime(fragCount, Strm.metadata["keytime"][i].asInt() * 10000); - fragref_box.setDuration(fragCount, Strm.metadata["keylen"][i].asInt() * 10000); - fragref_box.setFragmentCount(++fragCount); - } - } - traf_box.setContent(fragref_box, 3); - } - - MP4::MOOF moof_box; - moof_box.setContent(mfhd_box, 0); - moof_box.setContent(traf_box, 1); - - //Setting the correct offsets. - trun_box.setDataOffset(moof_box.boxedSize() + 8); - traf_box.setContent(trun_box, 1); - moof_box.setContent(traf_box, 1); - - //Send the complete message - HTTP_S.SetHeader("Content-Length", dataSize + 8 + moof_box.boxedSize()); - conn.SendNow(HTTP_S.BuildResponse("200", "OK")); - conn.SendNow(moof_box.asBox(), moof_box.boxedSize()); - - unsigned long size = htonl(dataSize + 8); - conn.SendNow((char*) &size, 4); - conn.SendNow("mdat", 4); - while (dataBuffer.size() > 0){ - conn.SendNow(dataBuffer.front()); - dataBuffer.pop_front(); - } - conn.SendNow("\r\n",2); - } - dataBuffer.clear(); - dataSize = 0; - } if (Strm.lastType() == DTSC::AUDIO || Strm.lastType() == DTSC::VIDEO){ //Select only the data that the client has requested. - dataBuffer.push_back(Strm.lastData()); - dataSize += Strm.lastData().size(); + int tmp = Util::getMS(); + conn.SendNow(Strm.lastData()); } } } diff --git a/src/converters/dtscfix.cpp b/src/converters/dtscfix.cpp index c48fc174..f941a3b6 100644 --- a/src/converters/dtscfix.cpp +++ b/src/converters/dtscfix.cpp @@ -10,9 +10,9 @@ namespace Converters { class HeaderEntryDTSC { public: - HeaderEntryDTSC() : totalSize(0), parts(0), lastKeyTime(-5000), trackID(0), firstms(-1), lastms(0), keynum(0) {} + HeaderEntryDTSC() : totalSize(0), lastKeyTime(-5000), trackID(0), firstms(-1), lastms(0), keynum(0) {} long long int totalSize; - long long int parts; + std::vector parts; long long int lastKeyTime; long long int trackID; long long int firstms; @@ -80,6 +80,7 @@ namespace Converters { it->second.removeMember("keynum"); it->second.removeMember("keydata"); it->second.removeMember("keyparts"); + it->second.removeMember("keys"); } F.selectTracks(tmp); @@ -138,39 +139,41 @@ namespace Converters { } if (trackData[currentID].type == "video"){ if (F.getJSON().isMember("keyframe")){ - if (trackData[currentID].totalSize){ - meta["tracks"][currentID]["keydata"].append(trackData[currentID].totalSize); + int newNum = meta["tracks"][currentID]["keys"].size(); + meta["tracks"][currentID]["keys"][newNum]["num"] = ++trackData[currentID].keynum; + meta["tracks"][currentID]["keys"][newNum]["time"] = F.getJSON()["time"]; + meta["tracks"][currentID]["keys"][newNum]["bpos"] = F.getLastReadPos(); + if (meta["tracks"][currentID]["keys"].size() > 1){ + meta["tracks"][currentID]["keys"][newNum - 1]["len"] = F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keys"][newNum - 1]["time"].asInt(); + meta["tracks"][currentID]["keys"][newNum - 1]["size"] = trackData[currentID].totalSize; trackData[currentID].totalSize = 0; - meta["tracks"][currentID]["keyparts"].append(trackData[currentID].parts); - trackData[currentID].parts = 0; - } - meta["tracks"][currentID]["keytime"].append(F.getJSON()["time"]); - meta["tracks"][currentID]["keybpos"].append(F.getLastReadPos()); - meta["tracks"][currentID]["keynum"].append( ++trackData[currentID].keynum); - if (meta["tracks"][currentID]["keytime"].size() > 1){ - meta["tracks"][currentID]["keylen"].append(F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keytime"][meta["tracks"][currentID]["keytime"].size() - 2].asInt()); + for (int i = 0; i < trackData[currentID].parts.size(); i++){ + meta["tracks"][currentID]["keys"][newNum - 1]["parts"].append(trackData[currentID].parts[i]); + } + trackData[currentID].parts.clear(); } } }else{ if ((F.getJSON()["time"].asInt() - trackData[currentID].lastKeyTime) > 5000){ trackData[currentID].lastKeyTime = F.getJSON()["time"].asInt(); - if (trackData[currentID].totalSize){ - meta["tracks"][currentID]["keydata"].append(trackData[currentID].totalSize); + int newNum = meta["tracks"][currentID]["keys"].size(); + meta["tracks"][currentID]["keys"][newNum]["num"] = ++trackData[currentID].keynum; + meta["tracks"][currentID]["keys"][newNum]["time"] = F.getJSON()["time"]; + meta["tracks"][currentID]["keys"][newNum]["bpos"] = F.getLastReadPos(); + if (meta["tracks"][currentID]["keys"].size() > 1){ + meta["tracks"][currentID]["keys"][newNum - 1]["len"] = F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keys"][newNum - 1]["time"].asInt(); + meta["tracks"][currentID]["keys"][newNum - 1]["size"] = trackData[currentID].totalSize; trackData[currentID].totalSize = 0; - meta["tracks"][currentID]["keyparts"].append(trackData[currentID].parts); - trackData[currentID].parts = 0; - } - meta["tracks"][currentID]["keytime"].append(F.getJSON()["time"]); - meta["tracks"][currentID]["keybpos"].append(F.getLastReadPos()); - meta["tracks"][currentID]["keynum"].append( ++trackData[currentID].keynum); - if (meta["tracks"][currentID]["keytime"].size() > 1){ - meta["tracks"][currentID]["keylen"].append(F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keytime"][meta["tracks"][currentID]["keytime"].size() - 2].asInt()); + for (int i = 0; i < trackData[currentID].parts.size(); i++){ + meta["tracks"][currentID]["keys"][newNum - 1]["parts"].append(trackData[currentID].parts[i]); + } + trackData[currentID].parts.clear(); } } } trackData[currentID].totalSize += F.getJSON()["data"].asString().size(); trackData[currentID].lastms = nowpack; - trackData[currentID].parts ++; + trackData[currentID].parts.push_back(F.getJSON()["data"].asString().size()); F.seekNext(); } @@ -178,10 +181,6 @@ namespace Converters { long long int lastms = -1; for (std::map::iterator it = trackData.begin(); it != trackData.end(); it++){ - meta["tracks"][it->first]["keydata"].append(it->second.totalSize); - it->second.totalSize = 0; - meta["tracks"][it->first]["keyparts"].append(it->second.parts); - it->second.parts = 0; if (it->second.firstms < firstms){ firstms = it->second.firstms; } @@ -200,31 +199,39 @@ namespace Converters { meta["tracks"][it->first]["trackid"] = nextFreeID ++; } meta["tracks"][it->first]["type"] = it->second.type; - int tmp = meta["tracks"][it->first]["keytime"].size(); + int tmp = meta["tracks"][it->first]["keys"].size(); if (tmp > 0){ - meta["tracks"][it->first]["keylen"].append(it->second.lastms - meta["tracks"][it->first]["keytime"][tmp - 1].asInt()); + meta["tracks"][it->first]["keys"][tmp - 1]["len"] = it->second.lastms - meta["tracks"][it->first]["keys"][tmp - 2]["time"].asInt(); + meta["tracks"][it->first]["keys"][tmp - 1]["size"] = it->second.totalSize; + for (int i = 0; i < trackData[it->first].parts.size(); i++){ + meta["tracks"][it->first]["keys"][tmp - 1]["parts"].append(trackData[currentID].parts[i]); + } }else{ - meta["tracks"][it->first]["keylen"].append(it->second.lastms); + meta["tracks"][it->first]["keys"][tmp]["len"] = it->second.lastms; + meta["tracks"][it->first]["keys"][tmp]["size"] = it->second.totalSize; + for (int i = 0; i < trackData[it->first].parts.size(); i++){ + meta["tracks"][it->first]["keys"][tmp]["parts"].append(trackData[currentID].parts[i]); + } } //calculate fragments meta["tracks"][it->first]["frags"].null(); long long int currFrag = -1; - for (unsigned int i = 0; i < meta["tracks"][it->first]["keytime"].size(); i++){ - if (meta["tracks"][it->first]["keytime"][i].asInt() / 10000 > currFrag){ - currFrag = meta["tracks"][it->first]["keytime"][i].asInt() / 10000; + for (JSON::ArrIter arrIt = meta["tracks"][it->first]["keys"].ArrBegin(); arrIt != meta["tracks"][it->first]["keys"].ArrEnd(); arrIt++) { + if ((*arrIt)["time"].asInt() / 10000 > currFrag){ + currFrag = (*arrIt)["time"].asInt() / 10000; long long int fragLen = 1; - long long int fragDur = meta["tracks"][it->first]["keylen"][i].asInt(); - for (unsigned int j = i + 1; j < meta["tracks"][it->first]["keytime"].size(); j++){ - if (meta["tracks"][it->first]["keytime"][j].asInt() / 10000 > currFrag || j == meta["tracks"][it->first]["keytime"].size() - 1){ + long long int fragDur = (*arrIt)["len"].asInt(); + for (JSON::ArrIter it2 = arrIt; it2 != meta["tracks"][it->first]["keys"].ArrEnd(); it2++){ + if ((*it2)["time"].asInt() / 10000 > currFrag || (it2 + 1) == meta["tracks"][it->first]["keys"].ArrEnd()){ JSON::Value thisFrag; - thisFrag["num"] = meta["tracks"][it->first]["keynum"][i]; + thisFrag["num"] = (*arrIt)["num"].asInt(); thisFrag["len"] = fragLen; thisFrag["dur"] = fragDur; meta["tracks"][it->first]["frags"].append(thisFrag); break; } - fragLen++; - fragDur += meta["tracks"][it->first]["keylen"][j].asInt(); + fragLen ++; + fragDur += (*it2)["len"].asInt(); } } } diff --git a/src/converters/dtscmerge.cpp b/src/converters/dtscmerge.cpp index 1b54ea35..51e80c70 100644 --- a/src/converters/dtscmerge.cpp +++ b/src/converters/dtscmerge.cpp @@ -84,26 +84,22 @@ namespace Converters { long long int mappedID = getNextFree(trackMapping); trackMapping[it->first].insert(std::pair(oldID,mappedID)); trackIt->second["trackid"] = mappedID; - for (int i = 0; i < trackIt->second["keytime"].size(); i++){ - ///\todo Update to new struct. + for (JSON::ArrIter keyIt = trackIt->second["keys"].ArrBegin(); keyIt != trackIt->second["keys"].ArrEnd(); keyIt++){ keyframeInfo tmpInfo; tmpInfo.fileName = it->first; tmpInfo.trackID = oldID; - tmpInfo.keyTime = trackIt->second["keytime"][i].asInt(); - tmpInfo.keyBPos = trackIt->second["keybpos"][i].asInt(); - tmpInfo.keyNum = trackIt->second["keynum"][i].asInt(); - tmpInfo.keyLen = trackIt->second["keylen"][i].asInt(); - if ( i < trackIt->second["keytime"].size() - 1 ){ - tmpInfo.endBPos = trackIt->second["keybpos"][i + 1].asInt(); + tmpInfo.keyTime = (*keyIt)["time"].asInt(); + tmpInfo.keyBPos = (*keyIt)["bpos"].asInt(); + tmpInfo.keyNum = (*keyIt)["num"].asInt(); + tmpInfo.keyLen = (*keyIt)["len"].asInt(); + if ((keyIt + 1) != trackIt->second["keys"].ArrEnd()){ + tmpInfo.endBPos = (*(keyIt + 1))["bpos"].asInt(); }else{ tmpInfo.endBPos = it->second.getBytePosEOF(); } - allSorted.insert(std::pair(trackIt->second["keytime"][i].asInt(),tmpInfo)); + allSorted.insert(std::pair((*keyIt)["time"].asInt(),tmpInfo)); } - trackIt->second.removeMember("keytime"); - trackIt->second.removeMember("keybpos"); - trackIt->second.removeMember("keynum"); - trackIt->second.removeMember("keylen"); + trackIt->second.removeMember("keys"); trackIt->second.removeMember("frags"); newMeta["tracks"][JSON::Value(mappedID).asString()] = trackIt->second; }