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
Reference in a new issue