Update to "keys" element instead of all different arrays.
This commit is contained in:
		
							parent
							
								
									6bde0a3581
								
							
						
					
					
						commit
						7e3c97355f
					
				
					 5 changed files with 176 additions and 167 deletions
				
			
		|  | @ -39,10 +39,20 @@ namespace Analysers { | ||||||
|     long long unsigned int bfrm_max = 0; |     long long unsigned int bfrm_max = 0; | ||||||
|     long long unsigned int bps = 0; |     long long unsigned int bps = 0; | ||||||
|      |      | ||||||
|  |     std::set<int> 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(); |     F.seekNext(); | ||||||
|     while ( !F.getJSON().isNull()){ |     while (F.getJSON()){ | ||||||
|       std::cout << F.getJSON().toPrettyString() << std::endl; |  | ||||||
|       nowpack = F.getJSON()["time"].asInt(); |       nowpack = F.getJSON()["time"].asInt(); | ||||||
|  |       std::cout << F.getJSON().toPrettyString() << std::endl; | ||||||
|       if (firstpack == 0){ |       if (firstpack == 0){ | ||||||
|         firstpack = nowpack; |         firstpack = nowpack; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  | @ -154,9 +154,7 @@ int main(int argc, char** argv){ | ||||||
|                   json_sts["vod"]["meta"] = meta; |                   json_sts["vod"]["meta"] = meta; | ||||||
|                   for (JSON::ObjIter oIt = json_sts["vod"]["meta"]["tracks"].ObjBegin(); oIt != json_sts["vod"]["meta"]["tracks"].ObjEnd(); oIt++){ |                   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("init"); | ||||||
|                     oIt->second.removeMember("keytime"); |                     oIt->second.removeMember("keys"); | ||||||
|                     oIt->second.removeMember("keybpos"); |  | ||||||
|                     oIt->second.removeMember("keynum"); |  | ||||||
|                     oIt->second.removeMember("frags"); |                     oIt->second.removeMember("frags"); | ||||||
|                   } |                   } | ||||||
|                   meta_sent = true; |                   meta_sent = true; | ||||||
|  | @ -232,6 +230,7 @@ int main(int argc, char** argv){ | ||||||
|         playing = 0; |         playing = 0; | ||||||
|       } |       } | ||||||
|       if (source.atKeyframe()){ |       if (source.atKeyframe()){ | ||||||
|  |         ///\todo Fix auto-delay on playing == -1.
 | ||||||
|         if (playing == -1 && meta["video"]["keyms"].asInt() > now - lastTime){ |         if (playing == -1 && meta["video"]["keyms"].asInt() > now - lastTime){ | ||||||
|           Util::sleep(meta["video"]["keyms"].asInt() - (now - lastTime)); |           Util::sleep(meta["video"]["keyms"].asInt() - (now - lastTime)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -73,7 +73,7 @@ namespace Connector_HTTP { | ||||||
|                 "Type=\"audio\" " |                 "Type=\"audio\" " | ||||||
|                 "QualityLevels=\"" << allAudio.size() << "\" " |                 "QualityLevels=\"" << allAudio.size() << "\" " | ||||||
|                 "Name=\"audio\" " |                 "Name=\"audio\" " | ||||||
|                 "Chunks=\"" << allAudio.ObjBegin()->second["keytime"].size() << "\" " |                 "Chunks=\"" << allAudio.ObjBegin()->second["keys"].size() << "\" " | ||||||
|                 "Url=\"Q({bitrate})/A({start time})\">\n"; |                 "Url=\"Q({bitrate})/A({start time})\">\n"; | ||||||
|       int index = 1; |       int index = 1; | ||||||
|       for (JSON::ObjIter oIt = allAudio.ObjBegin(); oIt != allAudio.ObjEnd(); oIt++){ |       for (JSON::ObjIter oIt = allAudio.ObjBegin(); oIt != allAudio.ObjEnd(); oIt++){ | ||||||
|  | @ -93,12 +93,12 @@ namespace Connector_HTTP { | ||||||
|                   "FourCC=\"AACL\" />\n"; |                   "FourCC=\"AACL\" />\n"; | ||||||
|         index++; |         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 << "<c "; |         Result << "<c "; | ||||||
|         if (i == 0){ |         if (keyIt == allAudio.ObjBegin()->second["keys"].ArrBegin()){ | ||||||
|           Result << "t=\"" << allAudio.ObjBegin()->second["keytime"][0u].asInt() * 10000 << "\" "; |           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 << "</StreamIndex>\n"; |       Result << "</StreamIndex>\n"; | ||||||
|     } |     } | ||||||
|  | @ -108,7 +108,7 @@ namespace Connector_HTTP { | ||||||
|                 "Type=\"video\" " |                 "Type=\"video\" " | ||||||
|                 "QualityLevels=\"" << allVideo.size() << "\" " |                 "QualityLevels=\"" << allVideo.size() << "\" " | ||||||
|                 "Name=\"video\" " |                 "Name=\"video\" " | ||||||
|                 "Chunks=\"" << allVideo.ObjBegin()->second["keytime"].size() << "\" " |                 "Chunks=\"" << allVideo.ObjBegin()->second["keys"].size() << "\" " | ||||||
|                 "Url=\"Q({bitrate})/V({start time})\" " |                 "Url=\"Q({bitrate})/V({start time})\" " | ||||||
|                 "MaxWidth=\"" << maxWidth << "\" " |                 "MaxWidth=\"" << maxWidth << "\" " | ||||||
|                 "MaxHeight=\"" << maxHeight << "\" " |                 "MaxHeight=\"" << maxHeight << "\" " | ||||||
|  | @ -133,12 +133,12 @@ namespace Connector_HTTP { | ||||||
|                   "FourCC=\"AVC1\" />\n"; |                   "FourCC=\"AVC1\" />\n"; | ||||||
|         index++; |         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 << "<c "; |         Result << "<c "; | ||||||
|         if (i == 0){ |         if (keyIt == allVideo.ObjBegin()->second["keys"].ArrBegin()){ | ||||||
|           Result << "t=\"" << allVideo.ObjBegin()->second["keytime"][i].asInt() * 10000 << "\" "; |           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 << "</StreamIndex>\n"; |       Result << "</StreamIndex>\n"; | ||||||
|     } |     } | ||||||
|  | @ -246,6 +246,7 @@ namespace Connector_HTTP { | ||||||
|             parseString = parseString.substr(parseString.find("(") + 1); |             parseString = parseString.substr(parseString.find("(") + 1); | ||||||
|             requestedTime = atoll(parseString.substr(0, parseString.find(")")).c_str()); |             requestedTime = atoll(parseString.substr(0, parseString.find(")")).c_str()); | ||||||
|             if (Strm.metadata.isMember("live")){ |             if (Strm.metadata.isMember("live")){ | ||||||
|  |               ///\todo Fix this for live stuff
 | ||||||
|               int seekable = Strm.canSeekms(requestedTime / 10000); |               int seekable = Strm.canSeekms(requestedTime / 10000); | ||||||
|               if (seekable == 0){ |               if (seekable == 0){ | ||||||
|                 // iff the fragment in question is available, check if the next is available too
 |                 // 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.
 |             //Seek to the right place and send a play-once for a single fragment.
 | ||||||
|             std::stringstream sstream; |             std::stringstream sstream; | ||||||
|  |             JSON::Value myRef; | ||||||
|             long long int selectedQuality = atoll(Quality.c_str()) / 8; |             long long int selectedQuality = atoll(Quality.c_str()) / 8; | ||||||
|             if (wantsVideo){ |             if (wantsVideo){ | ||||||
|               //Select the correct track ID
 |               //Select the correct track ID
 | ||||||
|               for (JSON::ObjIter vIt = allVideo.ObjBegin(); vIt != allVideo.ObjEnd(); vIt++){ |               for (JSON::ObjIter vIt = allVideo.ObjBegin(); vIt != allVideo.ObjEnd(); vIt++){ | ||||||
|                 if (vIt->second["bps"].asInt() == selectedQuality){ |                 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
 |               //Select the correct track ID
 | ||||||
|               for (JSON::ObjIter aIt = allAudio.ObjBegin(); aIt != allAudio.ObjEnd(); aIt++){ |               for (JSON::ObjIter aIt = allAudio.ObjBegin(); aIt != allAudio.ObjEnd(); aIt++){ | ||||||
|                 if (aIt->second["bps"].asInt() == selectedQuality){ |                 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"; |             sstream << "s " << (requestedTime / 10000) << "\no \n"; | ||||||
|             ss.SendNow(sstream.str().c_str()); |             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{ |           }else{ | ||||||
|             //We have a request for a Manifest, generate and send it.
 |             //We have a request for a Manifest, generate and send it.
 | ||||||
|             HTTP_S.Clean(); |             HTTP_S.Clean(); | ||||||
|  | @ -322,106 +415,10 @@ namespace Connector_HTTP { | ||||||
|         } |         } | ||||||
|         if (ss.spool()){ |         if (ss.spool()){ | ||||||
|           while (Strm.parsePacket(ss.Received())){ |           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){ |             if (Strm.lastType() == DTSC::AUDIO || Strm.lastType() == DTSC::VIDEO){ | ||||||
|               //Select only the data that the client has requested.
 |               //Select only the data that the client has requested.
 | ||||||
|               dataBuffer.push_back(Strm.lastData()); |               int tmp = Util::getMS(); | ||||||
|               dataSize += Strm.lastData().size(); |               conn.SendNow(Strm.lastData()); | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ | ||||||
| namespace Converters { | namespace Converters { | ||||||
|   class HeaderEntryDTSC { |   class HeaderEntryDTSC { | ||||||
|     public: |     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 totalSize; | ||||||
|       long long int parts; |       std::vector<long long int> parts; | ||||||
|       long long int lastKeyTime; |       long long int lastKeyTime; | ||||||
|       long long int trackID; |       long long int trackID; | ||||||
|       long long int firstms; |       long long int firstms; | ||||||
|  | @ -80,6 +80,7 @@ namespace Converters { | ||||||
|       it->second.removeMember("keynum"); |       it->second.removeMember("keynum"); | ||||||
|       it->second.removeMember("keydata"); |       it->second.removeMember("keydata"); | ||||||
|       it->second.removeMember("keyparts"); |       it->second.removeMember("keyparts"); | ||||||
|  |       it->second.removeMember("keys"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     F.selectTracks(tmp); |     F.selectTracks(tmp); | ||||||
|  | @ -138,39 +139,41 @@ namespace Converters { | ||||||
|       } |       } | ||||||
|       if (trackData[currentID].type == "video"){ |       if (trackData[currentID].type == "video"){ | ||||||
|         if (F.getJSON().isMember("keyframe")){ |         if (F.getJSON().isMember("keyframe")){ | ||||||
|           if (trackData[currentID].totalSize){ |           int newNum = meta["tracks"][currentID]["keys"].size(); | ||||||
|             meta["tracks"][currentID]["keydata"].append(trackData[currentID].totalSize); |           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; |             trackData[currentID].totalSize = 0; | ||||||
|             meta["tracks"][currentID]["keyparts"].append(trackData[currentID].parts); |             for (int i = 0; i < trackData[currentID].parts.size(); i++){ | ||||||
|             trackData[currentID].parts = 0; |               meta["tracks"][currentID]["keys"][newNum - 1]["parts"].append(trackData[currentID].parts[i]); | ||||||
|             } |             } | ||||||
|           meta["tracks"][currentID]["keytime"].append(F.getJSON()["time"]); |             trackData[currentID].parts.clear(); | ||||||
|           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()); |  | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }else{ |       }else{ | ||||||
|         if ((F.getJSON()["time"].asInt() - trackData[currentID].lastKeyTime) > 5000){ |         if ((F.getJSON()["time"].asInt() - trackData[currentID].lastKeyTime) > 5000){ | ||||||
|           trackData[currentID].lastKeyTime = F.getJSON()["time"].asInt(); |           trackData[currentID].lastKeyTime = F.getJSON()["time"].asInt(); | ||||||
|           if (trackData[currentID].totalSize){ |           int newNum = meta["tracks"][currentID]["keys"].size(); | ||||||
|             meta["tracks"][currentID]["keydata"].append(trackData[currentID].totalSize); |           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; |             trackData[currentID].totalSize = 0; | ||||||
|             meta["tracks"][currentID]["keyparts"].append(trackData[currentID].parts); |             for (int i = 0; i < trackData[currentID].parts.size(); i++){ | ||||||
|             trackData[currentID].parts = 0; |               meta["tracks"][currentID]["keys"][newNum - 1]["parts"].append(trackData[currentID].parts[i]); | ||||||
|             } |             } | ||||||
|           meta["tracks"][currentID]["keytime"].append(F.getJSON()["time"]); |             trackData[currentID].parts.clear(); | ||||||
|           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()); |  | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       trackData[currentID].totalSize += F.getJSON()["data"].asString().size(); |       trackData[currentID].totalSize += F.getJSON()["data"].asString().size(); | ||||||
|       trackData[currentID].lastms = nowpack; |       trackData[currentID].lastms = nowpack; | ||||||
|       trackData[currentID].parts ++; |       trackData[currentID].parts.push_back(F.getJSON()["data"].asString().size()); | ||||||
|       F.seekNext(); |       F.seekNext(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -178,10 +181,6 @@ namespace Converters { | ||||||
|     long long int lastms = -1; |     long long int lastms = -1; | ||||||
| 
 | 
 | ||||||
|     for (std::map<std::string,HeaderEntryDTSC>::iterator it = trackData.begin(); it != trackData.end(); it++){ |     for (std::map<std::string,HeaderEntryDTSC>::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){ |       if (it->second.firstms < firstms){ | ||||||
|         firstms = it->second.firstms; |         firstms = it->second.firstms; | ||||||
|       } |       } | ||||||
|  | @ -200,31 +199,39 @@ namespace Converters { | ||||||
|         meta["tracks"][it->first]["trackid"] = nextFreeID ++; |         meta["tracks"][it->first]["trackid"] = nextFreeID ++; | ||||||
|       } |       } | ||||||
|       meta["tracks"][it->first]["type"] = it->second.type; |       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){ |       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{ |       }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
 |       //calculate fragments
 | ||||||
|       meta["tracks"][it->first]["frags"].null(); |       meta["tracks"][it->first]["frags"].null(); | ||||||
|       long long int currFrag = -1; |       long long int currFrag = -1; | ||||||
|       for (unsigned int i = 0; i < meta["tracks"][it->first]["keytime"].size(); i++){ |       for (JSON::ArrIter arrIt = meta["tracks"][it->first]["keys"].ArrBegin(); arrIt != meta["tracks"][it->first]["keys"].ArrEnd(); arrIt++) { | ||||||
|         if (meta["tracks"][it->first]["keytime"][i].asInt() / 10000 > currFrag){ |         if ((*arrIt)["time"].asInt() / 10000 > currFrag){ | ||||||
|           currFrag = meta["tracks"][it->first]["keytime"][i].asInt() / 10000; |           currFrag = (*arrIt)["time"].asInt() / 10000; | ||||||
|           long long int fragLen = 1; |           long long int fragLen = 1; | ||||||
|           long long int fragDur = meta["tracks"][it->first]["keylen"][i].asInt(); |           long long int fragDur = (*arrIt)["len"].asInt(); | ||||||
|           for (unsigned int j = i + 1; j < meta["tracks"][it->first]["keytime"].size(); j++){ |           for (JSON::ArrIter it2 = arrIt; it2 != meta["tracks"][it->first]["keys"].ArrEnd(); it2++){ | ||||||
|             if (meta["tracks"][it->first]["keytime"][j].asInt() / 10000 > currFrag || j == meta["tracks"][it->first]["keytime"].size() - 1){ |             if ((*it2)["time"].asInt() / 10000 > currFrag || (it2 + 1) == meta["tracks"][it->first]["keys"].ArrEnd()){ | ||||||
|               JSON::Value thisFrag; |               JSON::Value thisFrag; | ||||||
|               thisFrag["num"] = meta["tracks"][it->first]["keynum"][i]; |               thisFrag["num"] = (*arrIt)["num"].asInt(); | ||||||
|               thisFrag["len"] = fragLen; |               thisFrag["len"] = fragLen; | ||||||
|               thisFrag["dur"] = fragDur; |               thisFrag["dur"] = fragDur; | ||||||
|               meta["tracks"][it->first]["frags"].append(thisFrag); |               meta["tracks"][it->first]["frags"].append(thisFrag); | ||||||
|               break; |               break; | ||||||
|             } |             } | ||||||
|             fragLen ++; |             fragLen ++; | ||||||
|             fragDur += meta["tracks"][it->first]["keylen"][j].asInt(); |             fragDur += (*it2)["len"].asInt(); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  | @ -84,26 +84,22 @@ namespace Converters { | ||||||
|           long long int mappedID = getNextFree(trackMapping); |           long long int mappedID = getNextFree(trackMapping); | ||||||
|           trackMapping[it->first].insert(std::pair<int,int>(oldID,mappedID)); |           trackMapping[it->first].insert(std::pair<int,int>(oldID,mappedID)); | ||||||
|           trackIt->second["trackid"] = mappedID; |           trackIt->second["trackid"] = mappedID; | ||||||
|           for (int i = 0; i < trackIt->second["keytime"].size(); i++){ |           for (JSON::ArrIter keyIt = trackIt->second["keys"].ArrBegin(); keyIt != trackIt->second["keys"].ArrEnd(); keyIt++){ | ||||||
|             ///\todo Update to new struct.
 |  | ||||||
|             keyframeInfo tmpInfo; |             keyframeInfo tmpInfo; | ||||||
|             tmpInfo.fileName = it->first; |             tmpInfo.fileName = it->first; | ||||||
|             tmpInfo.trackID = oldID; |             tmpInfo.trackID = oldID; | ||||||
|             tmpInfo.keyTime = trackIt->second["keytime"][i].asInt(); |             tmpInfo.keyTime = (*keyIt)["time"].asInt(); | ||||||
|             tmpInfo.keyBPos = trackIt->second["keybpos"][i].asInt(); |             tmpInfo.keyBPos = (*keyIt)["bpos"].asInt(); | ||||||
|             tmpInfo.keyNum = trackIt->second["keynum"][i].asInt(); |             tmpInfo.keyNum = (*keyIt)["num"].asInt(); | ||||||
|             tmpInfo.keyLen = trackIt->second["keylen"][i].asInt(); |             tmpInfo.keyLen = (*keyIt)["len"].asInt(); | ||||||
|             if ( i < trackIt->second["keytime"].size() - 1 ){ |             if ((keyIt + 1) != trackIt->second["keys"].ArrEnd()){ | ||||||
|               tmpInfo.endBPos = trackIt->second["keybpos"][i + 1].asInt(); |               tmpInfo.endBPos = (*(keyIt + 1))["bpos"].asInt(); | ||||||
|             }else{ |             }else{ | ||||||
|               tmpInfo.endBPos = it->second.getBytePosEOF(); |               tmpInfo.endBPos = it->second.getBytePosEOF(); | ||||||
|             } |             } | ||||||
|             allSorted.insert(std::pair<int,keyframeInfo>(trackIt->second["keytime"][i].asInt(),tmpInfo)); |             allSorted.insert(std::pair<int,keyframeInfo>((*keyIt)["time"].asInt(),tmpInfo)); | ||||||
|           } |           } | ||||||
|           trackIt->second.removeMember("keytime"); |           trackIt->second.removeMember("keys"); | ||||||
|           trackIt->second.removeMember("keybpos"); |  | ||||||
|           trackIt->second.removeMember("keynum"); |  | ||||||
|           trackIt->second.removeMember("keylen"); |  | ||||||
|           trackIt->second.removeMember("frags"); |           trackIt->second.removeMember("frags"); | ||||||
|           newMeta["tracks"][JSON::Value(mappedID).asString()] = trackIt->second; |           newMeta["tracks"][JSON::Value(mappedID).asString()] = trackIt->second; | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Erik Zandvliet
						Erik Zandvliet