From e2ef8c45d87bb00ff934ee7ba1b3fbef03ee9407 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 21 Mar 2013 14:21:22 +0100 Subject: [PATCH] Fixed and updated DTSCFix application. --- src/converters/dtscfix.cpp | 124 ++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 71 deletions(-) diff --git a/src/converters/dtscfix.cpp b/src/converters/dtscfix.cpp index f2128e2a..107cdc04 100644 --- a/src/converters/dtscfix.cpp +++ b/src/converters/dtscfix.cpp @@ -12,90 +12,48 @@ namespace Converters { /// Reads an DTSC file and attempts to fix the metadata in it. int DTSCFix(Util::Config & conf){ DTSC::File F(conf.getString("filename")); - JSON::Value oriheader = F.getMeta(); - JSON::Value meta = oriheader; + JSON::Value oriheader = F.getFirstMeta(); + JSON::Value meta = F.getMeta(); JSON::Value pack; if ( !oriheader.isMember("moreheader")){ - std::cerr << "This file is not DTSCFix'able. Please re-convert and try again." << std::endl; + std::cerr << "This file is too old to fix - please reconvert." << std::endl; return 1; } if (oriheader["moreheader"].asInt() > 0){ - std::cerr << "Warning: This file has already been DTSCFix'ed. Doing this multiple times makes the file larger for no reason." << std::endl; + if ((meta.isMember("keytime") && meta.isMember("keybpos") && meta.isMember("keynum") && meta.isMember("keylen") && meta.isMember("frags")) || !meta.isMember("video")){ + std::cerr << "This file was already fixed or doesn't need fixing - cancelling." << std::endl; + return 0; + } } meta.removeMember("keytime"); meta.removeMember("keybpos"); meta.removeMember("moreheader"); - long long unsigned int firstpack = 0; - long long unsigned int nowpack = 0; - long long unsigned int lastaudio = 0; - long long unsigned int lastvideo = 0; - long long unsigned int lastkey = 0; + long long int nowpack = 0; + long long int lastaudio = 0; + long long int lastvideo = 0; long long unsigned int totalvideo = 0; long long unsigned int totalaudio = 0; - long long unsigned int keyframes = 0; - long long unsigned int key_min = 0xffffffff; - long long unsigned int key_max = 0; - long long unsigned int vid_min = 0xffffffff; - long long unsigned int vid_max = 0; - long long unsigned int aud_min = 0xffffffff; - long long unsigned int aud_max = 0; - long long unsigned int bfrm_min = 0xffffffff; - long long unsigned int bfrm_max = 0; - long long unsigned int bps = 0; + long long int keynum = 0; F.seekNext(); while ( !F.getJSON().isNull()){ nowpack = F.getJSON()["time"].asInt(); - if (firstpack == 0){ - firstpack = nowpack; + if ( !meta.isMember("firstms")){ + meta["firstms"] = nowpack; } if (F.getJSON()["datatype"].asString() == "audio"){ - if (lastaudio != 0 && (nowpack - lastaudio) != 0){ - bps = F.getJSON()["data"].asString().size() / (nowpack - lastaudio); - if (bps < aud_min){ - aud_min = bps; - } - if (bps > aud_max){ - aud_max = bps; - } - } totalaudio += F.getJSON()["data"].asString().size(); lastaudio = nowpack; } if (F.getJSON()["datatype"].asString() == "video"){ - if (lastvideo != 0 && (nowpack - lastvideo) != 0){ - bps = F.getJSON()["data"].asString().size() / (nowpack - lastvideo); - if (bps < vid_min){ - vid_min = bps; - } - if (bps > vid_max){ - vid_max = bps; - } - } if (F.getJSON()["keyframe"].asInt() != 0){ meta["keytime"].append(F.getJSON()["time"]); meta["keybpos"].append(F.getLastReadPos()); - if (lastkey != 0){ - bps = nowpack - lastkey; - if (bps < key_min){ - key_min = bps; - } - if (bps > key_max){ - key_max = bps; - } - } - keyframes++; - lastkey = nowpack; - } - if (F.getJSON()["offset"].asInt() != 0){ - bps = F.getJSON()["offset"].asInt(); - if (bps < bfrm_min){ - bfrm_min = bps; - } - if (bps > bfrm_max){ - bfrm_max = bps; + meta["keynum"].append(++keynum); + if (meta["keytime"].size() > 1){ + meta["keylen"].append(F.getJSON()["time"].asInt() - meta["keytime"][meta["keytime"].size() - 2].asInt()); } } totalvideo += F.getJSON()["data"].asString().size(); @@ -104,35 +62,59 @@ namespace Converters { F.seekNext(); } - meta["length"] = (long long int)((nowpack - firstpack) / 1000); - meta["lastms"] = (long long int)nowpack; + meta["length"] = ((nowpack - meta["firstms"].asInt()) / 1000); + meta["lastms"] = nowpack; if (meta.isMember("audio")){ - meta["audio"]["bps"] = (long long int)(totalaudio / ((lastaudio - firstpack) / 1000)); + meta["audio"]["bps"] = (long long int)(totalaudio / ((lastaudio - meta["firstms"].asInt()) / 1000)); } if (meta.isMember("video")){ - meta["video"]["bps"] = (long long int)(totalvideo / ((lastvideo - firstpack) / 1000)); - meta["video"]["keyms"] = (long long int)((lastvideo - firstpack) / keyframes); - if (meta["video"]["keyms"].asInt() - key_min > key_max - meta["video"]["keyms"].asInt()){ - meta["video"]["keyvar"] = (long long int)(meta["video"]["keyms"].asInt() - key_min); + meta["video"]["bps"] = (long long int)(totalvideo / ((lastvideo - meta["firstms"].asInt()) / 1000)); + meta["video"]["keyms"] = ((lastvideo - meta["firstms"].asInt()) / meta["keytime"].size()); + //append last keylen element - keytime, keybpos, keynum and keylen are now complete + if (meta["keytime"].size() > 0){ + meta["keylen"].append(nowpack - meta["keytime"][meta["keytime"].size() - 1].asInt()); }else{ - meta["video"]["keyvar"] = (long long int)(key_max - meta["video"]["keyms"].asInt()); + meta["keylen"].append(nowpack); + } + //calculate fragments + meta["frags"].null(); + long long int currFrag = -1; + for (unsigned int i = 0; i < meta["keytime"].size(); i++){ + if (meta["keytime"][i].asInt() / 10000 > currFrag){ + currFrag = meta["keytime"][i].asInt() / 10000; + long long int fragLen = 1; + long long int fragDur = meta["keylen"][i].asInt(); + for (unsigned int j = i; j < meta["keytime"].size(); j++){ + if (meta["keytime"][j].asInt() / 10000 > currFrag || j == meta["keytime"].size()-1){ + JSON::Value thisFrag; + thisFrag["num"] = meta["keynum"][i]; + thisFrag["len"] = fragLen; + thisFrag["dur"] = fragDur; + meta["frags"].append(thisFrag); + break; + } + fragLen++; + fragDur += meta["keylen"][j].asInt(); + } + } } } - - std::cerr << "Appending new header..." << std::endl; + + //append the revised header std::string loader = meta.toPacked(); long long int newHPos = F.addHeader(loader); if ( !newHPos){ - std::cerr << "Failure appending new header. Cancelling." << std::endl; - return 1; + std::cerr << "Failure appending new header." << std::endl; + return -1; } - std::cerr << "Re-writing header..." << std::endl; + //re-write the original header with information about the location of the new one oriheader["moreheader"] = newHPos; loader = oriheader.toPacked(); if (F.writeHeader(loader)){ std::cerr << "Metadata is now: " << meta.toPrettyString(0) << std::endl; return 0; }else{ + std::cerr << "Failure rewriting header." << std::endl; return -1; } } //DTSCFix