diff --git a/src/app/FileProber.cpp b/src/app/FileProber.cpp index 2ca3706..6ecc901 100644 --- a/src/app/FileProber.cpp +++ b/src/app/FileProber.cpp @@ -16,7 +16,18 @@ using namespace libffmpeg; -const auto FILE_NAME = std::string("testFile.webm"); +void showUsage() +{ + std::cout << "FileProber usage:\n"; + std::cout << " FileProber [options]\n"; + std::cout << "\n"; + std::cout << "Options:\n"; + std::cout << " -showAllPackets Print all parsed packets\n"; + std::cout << " -loglevelDebug Set log level to debug output\n"; + std::cout << " -loglevelInfo Set log level to info output\n"; + std::cout << " -loglevelWarning Set log level to warning output\n"; + std::cout << " -libPath Set a search path for the ffmpeg libraries\n"; +} std::string to_string(const avcodec::CodecDescriptorProperties &properties) { @@ -57,19 +68,58 @@ std::string to_string(const ByteVector &bytes) return stream.str(); } +template std::string to_string(const std::map &map) +{ + std::ostringstream stream; + auto isFirst = false; + for (const auto [key, value] : map) + { + if (!isFirst) + stream << ", "; + stream << "[" << key << ", " << value << "]"; + isFirst = false; + } + return stream.str(); +} + struct Settings { + std::string filename{}; bool showPackets{}; std::filesystem::path libraryPath{}; libffmpeg::LogLevel logLevel{libffmpeg::LogLevel::Error}; }; -Settings parseCommandLineArguments(int argc, char const *argv[]) +bool checkIfFileExists(std::string_view filename) +{ + if (std::filesystem::exists(filename)) + return true; + + std::cout << "Given file " << filename << " not found."; + return false; +} + +std::optional parseCommandLineArguments(int argc, char const *argv[]) { Settings settings; + + if (1 == argc) + { + std::cout << "Not enough arguemnts. File name must be given"; + return {}; + } + for (int i = 1; i < argc; ++i) { const auto argument = std::string(argv[i]); + + if (1 == i) + { + if (checkIfFileExists(argument)) + settings.filename = argument; + else + return {}; + } if (argument == "-showAllPackets") settings.showPackets = true; if (argument == "-loglevelDebug") @@ -93,7 +143,10 @@ Settings parseCommandLineArguments(int argc, char const *argv[]) settings.libraryPath = path; } else + { std::cout << "Missing argument for parameter -libPath"; + return {}; + } } } return settings; @@ -112,9 +165,14 @@ void loggingFunction(const LogLevel logLevel, const std::string &message) int main(int argc, char const *argv[]) { const auto settings = parseCommandLineArguments(argc, argv); + if (!settings) + { + showUsage(); + return 1; + } const auto loadingResult = FFmpegLibrariesBuilder() - .withLoggingFunction(&loggingFunction, LogLevel::Debug) + .withLoggingFunction(&loggingFunction, settings->logLevel) .tryLoadingOfLibraries(); if (!loadingResult.ffmpegLibraries) @@ -135,12 +193,12 @@ int main(int argc, char const *argv[]) } Demuxer demuxer(loadingResult.ffmpegLibraries); - if (!demuxer.openFile(FILE_NAME)) + if (!demuxer.openFile(settings->filename)) { - std::cout << "Error when opening input file : " + FILE_NAME + "\n "; + std::cout << "Error when opening input file : " + settings->filename + "\n "; return 1; } - std::cout << "Successfully opened file " + FILE_NAME + ".\n"; + std::cout << "Successfully opened file " + settings->filename + ".\n"; const auto formatContext = demuxer.getFormatContext(); const auto inputFormat = formatContext->getInputFormat(); @@ -184,14 +242,39 @@ int main(int argc, char const *argv[]) } } - std::map streamPacketCounters; - int packetIndex = 0; + struct StreamCounters + { + int packetCount{0}; + std::map packetCountPerDuration{}; + std::map packetCountPerPtsIncrease{}; + std::map packetCountPerDtsIncrease{}; + }; + + std::map streamPacketCounters; + int packetIndex = 0; + std::map lastDTSPerStream; + std::map lastPTSPerStream; + while (auto packet = demuxer.getNextPacket()) { const auto streamIndex = packet->getStreamIndex(); - streamPacketCounters[streamIndex]++; - if (settings.showPackets) + if (lastDTSPerStream.count(streamIndex) > 0 && lastPTSPerStream.count(streamIndex) > 0) + { + const auto ptsIncrease = packet->getPTS().value() - lastPTSPerStream.at(streamIndex); + const auto dtsIncrease = packet->getDTS() - lastDTSPerStream.at(streamIndex); + + streamPacketCounters[streamIndex].packetCountPerPtsIncrease[ptsIncrease]++; + streamPacketCounters[streamIndex].packetCountPerDtsIncrease[dtsIncrease]++; + } + + lastPTSPerStream[streamIndex] = packet->getPTS().value(); + lastDTSPerStream[streamIndex] = packet->getDTS(); + + streamPacketCounters[streamIndex].packetCount++; + streamPacketCounters[streamIndex].packetCountPerDuration[packet->getDuration()]++; + + if (settings->showPackets) { auto ptsString = packet->getPTS() ? std::to_string(packet->getPTS().value()) : "No-PTS"; std::cout << " Packet " << packetIndex << ": StreamIndex " << packet->getStreamIndex() @@ -205,9 +288,18 @@ int main(int argc, char const *argv[]) packetIndex++; } - std::cout << " Packet counts:\n"; - for (const auto [streamIndex, count] : streamPacketCounters) - std::cout << " Stream " << streamIndex << " : " << count << "\n"; + std::cout << " Stream counts:\n"; + for (const auto [streamIndex, counters] : streamPacketCounters) + { + std::cout << " Stream " << streamIndex << " : \n"; + std::cout << " Packet count: " << counters.packetCount << "\n"; + std::cout << " Packet per duration: " << to_string(counters.packetCountPerDuration) + << "\n"; + std::cout << " Packet per PTS increase: " << to_string(counters.packetCountPerPtsIncrease) + << "\n"; + std::cout << " Packet per DTS increase: " << to_string(counters.packetCountPerDtsIncrease) + << "\n"; + } return 0; } diff --git a/src/lib/AVUtil/wrappers/AVMotionVectorConversion.h b/src/lib/AVUtil/wrappers/AVMotionVectorConversion.h index f661077..870e2aa 100644 --- a/src/lib/AVUtil/wrappers/AVMotionVectorConversion.h +++ b/src/lib/AVUtil/wrappers/AVMotionVectorConversion.h @@ -8,6 +8,7 @@ #include +#include #include namespace libffmpeg::avutil diff --git a/src/lib/AVUtil/wrappers/AVPixFmtDescriptorConversion.cpp b/src/lib/AVUtil/wrappers/AVPixFmtDescriptorConversion.cpp index dfb1153..98aa205 100644 --- a/src/lib/AVUtil/wrappers/AVPixFmtDescriptorConversion.cpp +++ b/src/lib/AVUtil/wrappers/AVPixFmtDescriptorConversion.cpp @@ -9,6 +9,8 @@ #include "AVPixFmtDescriptorConversionInternal.h" #include "CastUtilClasses.h" +#include + using namespace std::rel_ops; namespace libffmpeg::avutil