diff --git a/Project/QtCreator/qctools-QtAVPlayer b/Project/QtCreator/qctools-QtAVPlayer index 4f88dffda..9d4de8aef 160000 --- a/Project/QtCreator/qctools-QtAVPlayer +++ b/Project/QtCreator/qctools-QtAVPlayer @@ -1 +1 @@ -Subproject commit 4f88dffdad10b8924c08b89d86552e6d22435b99 +Subproject commit 9d4de8aefdb543ee6b4fb2cdb74c61b67172e8a2 diff --git a/Source/Cli/cli.cpp b/Source/Cli/cli.cpp index dcbde0ac2..4df44906f 100644 --- a/Source/Cli/cli.cpp +++ b/Source/Cli/cli.cpp @@ -4,6 +4,7 @@ #include "Core/CommonStats.h" #include "Core/FileInformation.h" #include +#include Cli::Cli() : indexOfStreamWithKnownFrameCount(0), statsFileBytesWritten(0), statsFileBytesTotal(0), statsFileBytesUploaded(0), statsFileBytesToUpload(0) { @@ -15,6 +16,7 @@ int Cli::exec(QCoreApplication &a) std::string appName = "qcli"; std::string copyright = "Copyright (C): 2013-2020, BAVC.\nCopyright (C): 2018-2020, RiceCapades LLC & MediaArea.net SARL."; Preferences prefs; + Logging logging; QString input; QString output; @@ -53,6 +55,9 @@ int Cli::exec(QCoreApplication &a) } else if(a.arguments().at(i) == "-u") { uploadToSignalServer = true; + } else if(a.arguments().at(i) == "--log") + { + logging.enable(); } else if(a.arguments().at(i) == "-uf") { forceUploadToSignalServer = true; @@ -567,10 +572,11 @@ int Cli::exec(QCoreApplication &a) bool mkvReport = output.endsWith(".qctools.mkv"); bool xmlGzReport = output.endsWith(".xml.gz"); + bool xmlReport = output.endsWith(".xml"); - if(!output.isEmpty() && !xmlGzReport && !mkvReport) + if(!output.isEmpty() && !xmlGzReport && !mkvReport && !xmlReport) { - std::cout << "warning: non-standard extension (not *.xml.gz) has been specified for output file. " << std::endl; + std::cout << "warning: non-standard extension (not *qctools.mkv, *.xml.gz or *.xml) has been specified for output file. " << std::endl; } QFile file(output); diff --git a/Source/Cli/main.cpp b/Source/Cli/main.cpp index c76f55632..66b76bf40 100644 --- a/Source/Cli/main.cpp +++ b/Source/Cli/main.cpp @@ -11,6 +11,8 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt int main(int argc, char *argv[]) { + qputenv("QT_AVPLAYER_NO_HWDEVICE", "1"); + qInstallMessageHandler(messageHandler); QCoreApplication a(argc, argv); diff --git a/Source/Core/AudioStats.cpp b/Source/Core/AudioStats.cpp index c76d045e7..812f28750 100644 --- a/Source/Core/AudioStats.cpp +++ b/Source/Core/AudioStats.cpp @@ -176,8 +176,9 @@ void AudioStats::parseFrame(tinyxml2::XMLElement *Frame) //*************************************************************************** //--------------------------------------------------------------------------- -void AudioStats::StatsFromFrame (struct AVFrame* Frame, int, int) +void AudioStats::StatsFromFrame (const QAVFrame& frame, int, int) { + auto Frame = frame.frame(); AVDictionary * m= Frame->metadata; AVDictionaryEntry* e=NULL; bool statsMapInitialized = !statsValueInfoByKeys.empty(); @@ -249,8 +250,10 @@ void AudioStats::StatsFromFrame (struct AVFrame* Frame, int, int) } //--------------------------------------------------------------------------- -void AudioStats::TimeStampFromFrame (struct AVFrame* Frame, size_t FramePos) +void AudioStats::TimeStampFromFrame (const QAVFrame& frame, size_t FramePos) { + auto Frame = frame.frame(); + if (Frequency==0) return; // Not supported @@ -259,9 +262,13 @@ void AudioStats::TimeStampFromFrame (struct AVFrame* Frame, size_t FramePos) x[0][FramePos]=FramePos; + /* can't use old way, take pts directly from frame int64_t ts=(Frame->pts == AV_NOPTS_VALUE)?Frame->pkt_dts : Frame->pts; // Using DTS is PTS is not available if (ts==AV_NOPTS_VALUE && FramePos) ts=(int64_t)((FirstTimeStamp+x[1][FramePos-1]+durations[FramePos-1])*Frequency); // If time stamp is not present, creating a fake one from last frame duration + */ + + int64_t ts = frame.pts() * 1000; if (ts!=AV_NOPTS_VALUE) { if (FirstTimeStamp==DBL_MAX) diff --git a/Source/Core/AudioStats.h b/Source/Core/AudioStats.h index 2ad0f7597..8e8516bbf 100644 --- a/Source/Core/AudioStats.h +++ b/Source/Core/AudioStats.h @@ -32,8 +32,8 @@ class AudioStats : public CommonStats // External data virtual void parseFrame(tinyxml2::XMLElement* frame); - void StatsFromFrame(struct AVFrame* Frame, int Width, int Height); - void TimeStampFromFrame(struct AVFrame* Frame, size_t FramePos); + void StatsFromFrame(const QAVFrame& Frame, int Width, int Height); + void TimeStampFromFrame(const QAVFrame& Frame, size_t FramePos); std::string StatsToXML(const activefilters& filters); }; diff --git a/Source/Core/CommonStats.h b/Source/Core/CommonStats.h index f770af78a..51cf810bd 100644 --- a/Source/Core/CommonStats.h +++ b/Source/Core/CommonStats.h @@ -28,6 +28,7 @@ namespace tinyxml2 { class XMLElement; } +class QAVFrame; class CommonStats { public: @@ -70,8 +71,8 @@ class CommonStats // External data void StatsFromExternalData_Finish() {Frequency=1; StatsFinish();} - virtual void StatsFromFrame(struct AVFrame* Frame, int Width, int Height) = 0; - virtual void TimeStampFromFrame(struct AVFrame* Frame, size_t FramePos) = 0; + virtual void StatsFromFrame(const QAVFrame& Frame, int Width, int Height) = 0; + virtual void TimeStampFromFrame(const QAVFrame& Frame, size_t FramePos) = 0; virtual void StatsFinish(); virtual std::string StatsToXML(const activefilters& filters) = 0; diff --git a/Source/Core/FileInformation.cpp b/Source/Core/FileInformation.cpp index 01f71a595..907e465c2 100644 --- a/Source/Core/FileInformation.cpp +++ b/Source/Core/FileInformation.cpp @@ -805,6 +805,7 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil QEventLoop loop; QMetaObject::Connection c; c = connect(m_mediaParser, &QAVPlayer::mediaStatusChanged, this, [&, this]() { + qDebug() << "m_mediaParser status after loading: " << m_mediaParser->mediaStatus(); loop.exit(); QObject::disconnect(c); }); @@ -983,6 +984,9 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil } } + for(auto& filter : filters) { + qDebug() << "applying filters: " << filter; + } m_mediaParser->setFilters(filters); QObject::connect(m_mediaParser, &QAVPlayer::audioFrame, m_mediaParser, [this](const QAVAudioFrame &frame) { @@ -990,8 +994,8 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil auto stat = Stats[frame.stream().index()]; - stat->TimeStampFromFrame(frame.frame(), stat->x_Current); - stat->StatsFromFrame(frame.frame(), 0, 0); + stat->TimeStampFromFrame(frame, stat->x_Current); + stat->StatsFromFrame(frame, 0, 0); }, // Qt::QueuedConnection @@ -1004,8 +1008,8 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil if(frame.filterName() == "stats") { auto stat = Stats[frame.stream().index()]; - stat->TimeStampFromFrame(frame.frame(), stat->x_Current); - stat->StatsFromFrame(frame.frame(), frame.size().width(), frame.size().height()); + stat->TimeStampFromFrame(frame, stat->x_Current); + stat->StatsFromFrame(frame, frame.size().width(), frame.size().height()); } else if(frame.filterName().startsWith(panelOutputPrefix)) { auto indexString = frame.filterName().mid(panelOutputPrefix.length()); @@ -1028,6 +1032,8 @@ FileInformation::FileInformation (SignalServer* signalServer, const QString &Fil ); QObject::connect(m_mediaParser, &QAVPlayer::mediaStatusChanged, [this](QAVPlayer::MediaStatus status) { + qDebug() << "m_mediaParser => mediaStatusChanged: " << status; + if(status == QAVPlayer::EndOfMedia) { for (size_t Pos=0; Posopen(QIODevice::ReadWrite)) { - if(name.endsWith(".qctools.xml")) + if (name.endsWith(".qctools.xml")) { auto bytesLeft = Data.str().size(); auto writePtr = DataS.c_str(); auto totalBytesWritten = 0; - while(bytesLeft) { + while (bytesLeft) { auto bytesToWrite = std::min(size_t(Buffer_Size), bytesLeft); auto bytesWritten = file->write(writePtr, bytesToWrite); totalBytesWritten += bytesWritten; @@ -1261,9 +1271,13 @@ void FileInformation::Export_XmlGz (const QString &ExportFileName, const activef writePtr += bytesToWrite; bytesLeft -= bytesWritten; - if(bytesWritten != bytesToWrite) + if (bytesWritten != bytesToWrite) break; } + } + else if (name.endsWith(".xml")) + { + file->write(DataS.c_str(), DataS.length()); } else { char* Buffer=new char[Buffer_Size]; z_stream strm; diff --git a/Source/Core/VideoStats.cpp b/Source/Core/VideoStats.cpp index 1c17caca8..43f87c635 100644 --- a/Source/Core/VideoStats.cpp +++ b/Source/Core/VideoStats.cpp @@ -255,8 +255,9 @@ void VideoStats::parseFrame(tinyxml2::XMLElement *Frame) //--------------------------------------------------------------------------- -void VideoStats::StatsFromFrame (struct AVFrame* Frame, int Width, int Height) +void VideoStats::StatsFromFrame (const QAVFrame& frame, int Width, int Height) { + auto Frame = frame.frame(); AVDictionary * m= Frame->metadata; AVDictionaryEntry* e=NULL; bool statsMapInitialized = !statsValueInfoByKeys.empty(); @@ -368,8 +369,10 @@ void VideoStats::StatsFromFrame (struct AVFrame* Frame, int Width, int Height) } //--------------------------------------------------------------------------- -void VideoStats::TimeStampFromFrame (struct AVFrame* Frame, size_t FramePos) +void VideoStats::TimeStampFromFrame (const QAVFrame& frame, size_t FramePos) { + auto Frame = frame.frame(); + if (Frequency==0) return; // Not supported diff --git a/Source/Core/VideoStats.h b/Source/Core/VideoStats.h index 1d57e623a..08a7d9f24 100644 --- a/Source/Core/VideoStats.h +++ b/Source/Core/VideoStats.h @@ -33,8 +33,8 @@ class VideoStats : public CommonStats // External data virtual void parseFrame(tinyxml2::XMLElement* frame); - void StatsFromFrame(struct AVFrame* Frame, int Width, int Height); - void TimeStampFromFrame(struct AVFrame* Frame, size_t FramePos); + void StatsFromFrame(const QAVFrame& Frame, int Width, int Height); + void TimeStampFromFrame(const QAVFrame& Frame, size_t FramePos); std::string StatsToXML(const activefilters& filters); int getWidth() const; diff --git a/Source/GUI/mainwindow_More.cpp b/Source/GUI/mainwindow_More.cpp index 5007a2fe2..206eef9f1 100755 --- a/Source/GUI/mainwindow_More.cpp +++ b/Source/GUI/mainwindow_More.cpp @@ -489,6 +489,8 @@ void MainWindow::addFile(const QString &FileName) if (FileName.isEmpty()) return; + qDebug() << "addFile: " << FileName; + // Launch analysis FileInformation* Temp=new FileInformation(signalServer, FileName, Prefs->ActiveFilters, Prefs->ActiveAllTracks, preferences->getActivePanels(), preferences->createQCvaultFileNameString(FileName)); if (!Temp->isValid() && !Temp->hasStats())