Fixed and updated DTSCFix application.
This commit is contained in:
parent
6c464ae6f0
commit
e2ef8c45d8
1 changed files with 53 additions and 71 deletions
|
@ -12,90 +12,48 @@ namespace Converters {
|
||||||
/// Reads an DTSC file and attempts to fix the metadata in it.
|
/// Reads an DTSC file and attempts to fix the metadata in it.
|
||||||
int DTSCFix(Util::Config & conf){
|
int DTSCFix(Util::Config & conf){
|
||||||
DTSC::File F(conf.getString("filename"));
|
DTSC::File F(conf.getString("filename"));
|
||||||
JSON::Value oriheader = F.getMeta();
|
JSON::Value oriheader = F.getFirstMeta();
|
||||||
JSON::Value meta = oriheader;
|
JSON::Value meta = F.getMeta();
|
||||||
JSON::Value pack;
|
JSON::Value pack;
|
||||||
|
|
||||||
if ( !oriheader.isMember("moreheader")){
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
if (oriheader["moreheader"].asInt() > 0){
|
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("keytime");
|
||||||
meta.removeMember("keybpos");
|
meta.removeMember("keybpos");
|
||||||
meta.removeMember("moreheader");
|
meta.removeMember("moreheader");
|
||||||
|
|
||||||
long long unsigned int firstpack = 0;
|
long long int nowpack = 0;
|
||||||
long long unsigned int nowpack = 0;
|
long long int lastaudio = 0;
|
||||||
long long unsigned int lastaudio = 0;
|
long long int lastvideo = 0;
|
||||||
long long unsigned int lastvideo = 0;
|
|
||||||
long long unsigned int lastkey = 0;
|
|
||||||
long long unsigned int totalvideo = 0;
|
long long unsigned int totalvideo = 0;
|
||||||
long long unsigned int totalaudio = 0;
|
long long unsigned int totalaudio = 0;
|
||||||
long long unsigned int keyframes = 0;
|
long long int keynum = 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;
|
|
||||||
|
|
||||||
F.seekNext();
|
F.seekNext();
|
||||||
while ( !F.getJSON().isNull()){
|
while ( !F.getJSON().isNull()){
|
||||||
nowpack = F.getJSON()["time"].asInt();
|
nowpack = F.getJSON()["time"].asInt();
|
||||||
if (firstpack == 0){
|
if ( !meta.isMember("firstms")){
|
||||||
firstpack = nowpack;
|
meta["firstms"] = nowpack;
|
||||||
}
|
}
|
||||||
if (F.getJSON()["datatype"].asString() == "audio"){
|
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();
|
totalaudio += F.getJSON()["data"].asString().size();
|
||||||
lastaudio = nowpack;
|
lastaudio = nowpack;
|
||||||
}
|
}
|
||||||
if (F.getJSON()["datatype"].asString() == "video"){
|
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){
|
if (F.getJSON()["keyframe"].asInt() != 0){
|
||||||
meta["keytime"].append(F.getJSON()["time"]);
|
meta["keytime"].append(F.getJSON()["time"]);
|
||||||
meta["keybpos"].append(F.getLastReadPos());
|
meta["keybpos"].append(F.getLastReadPos());
|
||||||
if (lastkey != 0){
|
meta["keynum"].append(++keynum);
|
||||||
bps = nowpack - lastkey;
|
if (meta["keytime"].size() > 1){
|
||||||
if (bps < key_min){
|
meta["keylen"].append(F.getJSON()["time"].asInt() - meta["keytime"][meta["keytime"].size() - 2].asInt());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalvideo += F.getJSON()["data"].asString().size();
|
totalvideo += F.getJSON()["data"].asString().size();
|
||||||
|
@ -104,35 +62,59 @@ namespace Converters {
|
||||||
F.seekNext();
|
F.seekNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
meta["length"] = (long long int)((nowpack - firstpack) / 1000);
|
meta["length"] = ((nowpack - meta["firstms"].asInt()) / 1000);
|
||||||
meta["lastms"] = (long long int)nowpack;
|
meta["lastms"] = nowpack;
|
||||||
if (meta.isMember("audio")){
|
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")){
|
if (meta.isMember("video")){
|
||||||
meta["video"]["bps"] = (long long int)(totalvideo / ((lastvideo - firstpack) / 1000));
|
meta["video"]["bps"] = (long long int)(totalvideo / ((lastvideo - meta["firstms"].asInt()) / 1000));
|
||||||
meta["video"]["keyms"] = (long long int)((lastvideo - firstpack) / keyframes);
|
meta["video"]["keyms"] = ((lastvideo - meta["firstms"].asInt()) / meta["keytime"].size());
|
||||||
if (meta["video"]["keyms"].asInt() - key_min > key_max - meta["video"]["keyms"].asInt()){
|
//append last keylen element - keytime, keybpos, keynum and keylen are now complete
|
||||||
meta["video"]["keyvar"] = (long long int)(meta["video"]["keyms"].asInt() - key_min);
|
if (meta["keytime"].size() > 0){
|
||||||
|
meta["keylen"].append(nowpack - meta["keytime"][meta["keytime"].size() - 1].asInt());
|
||||||
}else{
|
}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();
|
std::string loader = meta.toPacked();
|
||||||
long long int newHPos = F.addHeader(loader);
|
long long int newHPos = F.addHeader(loader);
|
||||||
if ( !newHPos){
|
if ( !newHPos){
|
||||||
std::cerr << "Failure appending new header. Cancelling." << std::endl;
|
std::cerr << "Failure appending new header." << std::endl;
|
||||||
return 1;
|
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;
|
oriheader["moreheader"] = newHPos;
|
||||||
loader = oriheader.toPacked();
|
loader = oriheader.toPacked();
|
||||||
if (F.writeHeader(loader)){
|
if (F.writeHeader(loader)){
|
||||||
std::cerr << "Metadata is now: " << meta.toPrettyString(0) << std::endl;
|
std::cerr << "Metadata is now: " << meta.toPrettyString(0) << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
|
std::cerr << "Failure rewriting header." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} //DTSCFix
|
} //DTSCFix
|
||||||
|
|
Loading…
Add table
Reference in a new issue