Permalink
Browse files

Add a video performance test to mythavtest.

The test disables audio, subtitling, OSD, video filtering (including
deinterlacing) and simply tries to decode/display frames as fast as
possible. Should prove useful for comparative and regression testing. I
may add an extra option to enable deinterlacing to assess its impact on
performance. The playback profile (decoder, video output) will be driven
by the mythfrontend settings.

Specify the file to test with -f or --file (any directly accessible file
or valid url) and request a test with -t or --test.

Optionally adjust the test duration with -s or --seconds (defaults to 5)
or request a decoder only test with -d or --decodeonly (frames are just
decoded and not otherwise processed or displayed).

Look to the log output for the results.

N.B. many display methods will be rate limited due to sync-to-vblank
being enabled. This is unavoidable in some cases (e.g. VDPAU), can be
turned off for others (e.g. most linux OpenGL implementations) and
others will need changes to the code to allow disabling them (e.g.
XVideo, OpenGL on OSX).
  • Loading branch information...
1 parent 5f923d3 commit 6c3d21a2be2835005f81744715ebd79f29402caf Mark Kendall committed Oct 26, 2011
@@ -107,6 +107,7 @@ class MTV_PUBLIC MythPlayer
friend class SubtitleScreen;
friend class InteractiveScreen;
friend class BDOverlayScreen;
+ friend class VideoPerformanceTest;
// TODO remove these
friend class TV;
friend class Transcode;
@@ -26,5 +26,26 @@ void MythAVTestCommandLineParser::LoadArguments(void)
addGeometry();
addDisplay();
addLogging();
+ add(QStringList(QStringList() << "-f" << "--file"), "file", "",
+ "Specify the file to play.", "");
+ add(QStringList(QStringList() << "-t" << "--test"), "test", false,
+ "Test video performance.",
+ "Test and debug video playback performance."
+ "Audio, captions, deinterlacing and the On Screen Display will all "
+ "be disabled and video will be displayed at the fastest possible rate. ")
+ ->SetGroup("Video Performance Testing")
+ ->SetRequires("file");
+ add(QStringList(QStringList() << "-d" << "--decodeonly"),
+ "decodeonly", false,
+ "Decode video frames but do not display them.",
+ "")
+ ->SetGroup("Video Performance Testing")
+ ->SetRequires("test")
+ ->SetRequires("file");
+ add(QStringList(QStringList() << "-s" << "--seconds"), "seconds", "",
+ "The number of seconds to run the test (default 5).", "")
+ ->SetGroup("Video Performance Testing")
+ ->SetRequires("test")
+ ->SetRequires("file");
}
@@ -7,10 +7,13 @@ using namespace std;
#include <QRegExp>
#include <QDir>
#include <QApplication>
+#include <QDateTime>
#include "tv_play.h"
#include "programinfo.h"
#include "commandlineparser.h"
+#include "mythplayer.h"
+#include "jitterometer.h"
#include "exitcodes.h"
#include "mythcontext.h"
@@ -24,6 +27,115 @@ using namespace std;
#include "mythuihelper.h"
#include "mythmainwindow.h"
+class VideoPerformanceTest
+{
+ public:
+ VideoPerformanceTest(const QString &filename, bool novsync, bool onlydecode,
+ int runfor)
+ : file(filename), novideosync(novsync), decodeonly(onlydecode),
+ secondstorun(runfor), ctx(NULL)
+ {
+ if (secondstorun < 1)
+ secondstorun = 1;
+ if (secondstorun > 3600)
+ secondstorun = 3600;
+ }
+
+ ~VideoPerformanceTest()
+ {
+ delete ctx;
+ }
+
+ void Test(void)
+ {
+ PIPMap dummy;
+
+ if (novideosync) // TODO
+ LOG(VB_GENERAL, LOG_INFO, "Will attempt to disable sync-to-vblank.");
+
+ RingBuffer *rb = RingBuffer::Create(file, false, true, 2000);
+ MythPlayer *mp = new MythPlayer(true);
+ mp->GetAudio()->SetAudioInfo("NULL", "NULL", 0, 0);
+ mp->GetAudio()->SetNoAudio();
+ ctx = new PlayerContext("VideoPerformanceTest");
+ ctx->SetRingBuffer(rb);
+ ctx->SetPlayer(mp);
+ ctx->SetPlayingInfo(new ProgramInfo(file));
+ mp->SetPlayerInfo(NULL, GetMythMainWindow(), true, ctx);
+
+ if (!mp->StartPlaying())
+ {
+ LOG(VB_GENERAL, LOG_ERR, "Failed to start playback.");
+ return;
+ }
+
+ VideoOutput *vo = mp->GetVideoOutput();
+ if (!vo)
+ {
+ LOG(VB_GENERAL, LOG_ERR, "No video output.");
+ return;
+ }
+
+ LOG(VB_GENERAL, LOG_INFO, "-----------------------------------");
+ LOG(VB_GENERAL, LOG_INFO, QString("Starting video performance test for '%1'.")
+ .arg(file));
+ LOG(VB_GENERAL, LOG_INFO, QString("Test will run for %1 seconds.")
+ .arg(secondstorun));
+
+ if (decodeonly)
+ LOG(VB_GENERAL, LOG_INFO, "Decoding frames only - skipping display.");
+
+ Jitterometer *jitter = new Jitterometer("Performance: ", mp->GetFrameRate());
+
+ int ms = secondstorun * 1000;
+ QDateTime start = QDateTime::currentDateTime();
+ while (1)
+ {
+ if (start.msecsTo(QDateTime::currentDateTime()) > ms)
+ {
+ LOG(VB_GENERAL, LOG_INFO, "Complete.");
+ break;
+ }
+
+ if (mp->IsErrored())
+ {
+ LOG(VB_GENERAL, LOG_ERR, "Playback error.");
+ break;
+ }
+
+ if (mp->GetEof())
+ {
+ LOG(VB_GENERAL, LOG_INFO, "End of file.");
+ break;
+ }
+
+ if (!mp->PrebufferEnoughFrames())
+ continue;
+
+ mp->SetBuffering(false);
+ vo->StartDisplayingFrame();
+ VideoFrame *frame = vo->GetLastShownFrame();
+ mp->CheckAspectRatio(frame);
+
+ if (!decodeonly)
+ {
+ vo->ProcessFrame(frame, NULL, NULL, dummy, kScan_Progressive);
+ vo->PrepareFrame(frame, kScan_Progressive, NULL);
+ vo->Show(kScan_Progressive);
+ }
+ vo->DoneDisplayingFrame(frame);
+ jitter->RecordCycleTime();
+ }
+ LOG(VB_GENERAL, LOG_INFO, "-----------------------------------");
+ }
+
+ private:
+ QString file;
+ bool novideosync;
+ bool decodeonly;
+ int secondstorun;
+ PlayerContext *ctx;
+};
int main(int argc, char *argv[])
{
@@ -64,7 +176,9 @@ int main(int argc, char *argv[])
}
QString filename = "";
- if (cmdline.GetArgs().size() >= 1)
+ if (!cmdline.toString("file").isEmpty())
+ filename = cmdline.toString("file");
+ else if (cmdline.GetArgs().size() >= 1)
filename = cmdline.GetArgs()[0];
gContext = new MythContext(MYTH_BINARY_VERSION);
@@ -105,25 +219,37 @@ int main(int argc, char *argv[])
MythMainWindow *mainWindow = GetMythMainWindow();
mainWindow->Init();
- TV::InitKeys();
-
- if (!UpgradeTVDatabaseSchema(false))
- {
- LOG(VB_GENERAL, LOG_ERR, "Fatal Error: Incorrect database schema.");
- delete gContext;
- return GENERIC_EXIT_DB_OUTOFDATE;
- }
-
- if (filename.isEmpty())
+ if (cmdline.toBool("test"))
{
- TV::StartTV(NULL, kStartTVNoFlags);
+ int seconds = 5;
+ if (!cmdline.toString("seconds").isEmpty())
+ seconds = cmdline.toInt("seconds");
+ VideoPerformanceTest *test = new VideoPerformanceTest(filename, false,
+ cmdline.toBool("decodeonly"), seconds);
+ test->Test();
+ delete test;
}
else
{
- ProgramInfo pginfo(filename);
- TV::StartTV(&pginfo, kStartTVNoFlags);
- }
+ TV::InitKeys();
+
+ if (!UpgradeTVDatabaseSchema(false))
+ {
+ LOG(VB_GENERAL, LOG_ERR, "Fatal Error: Incorrect database schema.");
+ delete gContext;
+ return GENERIC_EXIT_DB_OUTOFDATE;
+ }
+ if (filename.isEmpty())
+ {
+ TV::StartTV(NULL, kStartTVNoFlags);
+ }
+ else
+ {
+ ProgramInfo pginfo(filename);
+ TV::StartTV(&pginfo, kStartTVNoFlags);
+ }
+ }
DestroyMythMainWindow();
delete gContext;

0 comments on commit 6c3d21a

Please sign in to comment.