/// \file dtsc_analyser.cpp /// Reads an DTSC file and prints all readable data about it #include #include #include #include #include #include #include #include ///\brief Holds everything unique to the analysers. namespace Analysers { ///\brief Debugging tool for DTSC data. /// /// Expects DTSC data in a file given on the command line, outputs human-readable information to stderr. ///\param conf The configuration parsed from the commandline. ///\return The return code of the analyser. int analyseDTSC(Util::Config conf){ DTSC::File F(conf.getString("filename")); if (!F){ std::cerr << "Not a valid DTSC file" << std::endl; return 1; } if (conf.getBool("compact")){ JSON::Value result; for (std::map::iterator it = F.getMeta().tracks.begin(); it != F.getMeta().tracks.end(); it++){ JSON::Value track; if (it->second.type=="video"){ std::stringstream tStream; track["resolution"] = JSON::Value((long long)it->second.width).asString() + "x" + JSON::Value((long long)it->second.height).asString(); track["fps"] = (long long)((double)it->second.fpks / 1000); track["fpks"] = it->second.fpks; tStream << it->second.bps * 8 << " b/s, " << (double)it->second.bps * 8 / 1024 << " kb/s, " << (double)it->second.bps * 8 / 1024 / 1024 << " mb/s"; track["bitrate"] = tStream.str(); tStream.str(""); track["keyframe_duration"] = (long long)((float)(it->second.lastms - it->second.firstms) / it->second.keys.size()); tStream << ((double)(it->second.lastms - it->second.firstms) / it->second.keys.size()) / 1000; track["keyframe_interval"] = tStream.str(); tStream.str(""); if (it->second.codec == "H264"){ h264::sequenceParameterSet sps; sps.fromDTSCInit(it->second.init); h264::SPSMeta spsData = sps.getCharacteristics(); track["encoding"]["width"] = spsData.width; track["encoding"]["height"] = spsData.height; tStream << spsData.fps; track["encoding"]["fps"] = tStream.str(); track["encoding"]["profile"] = spsData.profile; track["encoding"]["level"] = spsData.level; } } if (it->second.type == "audio"){ std::stringstream tStream; tStream << it->second.bps * 8 << " b/s, " << (double)it->second.bps * 8 / 1024 << " kb/s, " << (double)it->second.bps * 8 / 1024 / 1024 << " mb/s"; track["bitrate"] = tStream.str(); track["keyframe_interval"] = (long long)((float)(it->second.lastms - it->second.firstms) / it->second.keys.size()); } result[it->second.getWritableIdentifier()] = track; } std::cout << result.toString(); return 0; } if (F.getMeta().vod || F.getMeta().live){ F.getMeta().toPrettyString(std::cout,0, 0x03); } int bPos = 0; F.seek_bpos(0); F.parseNext(); while (F.getPacket()){ switch (F.getPacket().getVersion()){ case DTSC::DTSC_V1: { std::cout << "DTSCv1 packet: " << F.getPacket().getScan().toPrettyString() << std::endl; break; } case DTSC::DTSC_V2: { std::cout << "DTSCv2 packet (Track " << F.getPacket().getTrackId() << ", time " << F.getPacket().getTime() << "): " << F.getPacket().getScan().toPrettyString() << std::endl; break; } case DTSC::DTSC_HEAD: { std::cout << "DTSC header: " << F.getPacket().getScan().toPrettyString() << std::endl; break; } case DTSC::DTCM: { std::cout << "DTCM command: " << F.getPacket().getScan().toPrettyString() << std::endl; break; } default: DEBUG_MSG(DLVL_WARN,"Invalid dtsc packet @ bpos %d", bPos); break; } bPos = F.getBytePos(); F.parseNext(); } return 0; } } /// Reads an DTSC file and prints all readable data about it int main(int argc, char ** argv){ Util::Config conf = Util::Config(argv[0]); conf.addOption("filename", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the DTSC file to analyse.\"}")); conf.addOption("compact", JSON::fromString("{\"short\": \"c\", \"long\": \"compact\", \"help\":\"Filename of the DTSC file to analyse.\"}")); conf.parseArgs(argc, argv); return Analysers::analyseDTSC(conf); } //main