1
0
Fork 0

Move stuff to MPVCommon namespace for shareding across MPV backends.

This commit is contained in:
namedkitten 2020-04-17 12:32:23 +01:00
parent 299ee556a9
commit f7167ee478
10 changed files with 586 additions and 970 deletions

View file

@ -50,6 +50,7 @@ set(SOURCES
src/ThumbnailCache.cpp src/ThumbnailCache.cpp
src/logger.cpp src/logger.cpp
src/qmldebugger.cpp src/qmldebugger.cpp
src/Backends/MPVCommon/MPVCommon.cpp
src/Backends/MPV/MPVBackend.cpp src/Backends/MPV/MPVBackend.cpp
src/Backends/MPVNoFBO/MPVNoFBOBackend.cpp src/Backends/MPVNoFBO/MPVNoFBOBackend.cpp
) )

View file

@ -1,5 +1,4 @@
#include "src/Backends/MPV/MPVBackend.hpp" #include "src/Backends/MPV/MPVBackend.hpp"
#include "src/logger.h"
#include "src/utils.hpp" #include "src/utils.hpp"
#include <QApplication> #include <QApplication>
#include <QElapsedTimer> #include <QElapsedTimer>
@ -19,11 +18,11 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#include "src/Backends/MPVCommon/MPVCommon.hpp"
bool usedirect = false; bool usedirect = false;
auto mpvLogger = initLogger("mpv");
namespace { namespace {
void void
@ -140,10 +139,10 @@ MPVBackend::MPVBackend(QQuickItem* parent)
if (!mpv) if (!mpv)
throw std::runtime_error("could not create mpv context"); throw std::runtime_error("could not create mpv context");
std::cout << QString("Direct: ").toUtf8().constData() << QString(usedirect ? "true" : "false").toUtf8().constData(); QSettings settings;
usedirect = settings.value("Backend/direct", false).toBool();
mpv_set_option_string(mpv, "terminal", "false");
mpv_set_option_string(mpv, "terminal", "on");
mpv_set_option_string(mpv, "msg-level", "all=v"); mpv_set_option_string(mpv, "msg-level", "all=v");
// Fix? // Fix?
@ -170,7 +169,7 @@ MPVBackend::MPVBackend(QQuickItem* parent)
mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE); mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE);
mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE);
mpv_request_log_messages(mpv, "verbose"); mpv_request_log_messages(mpv, "v");
mpv_set_wakeup_callback(mpv, wakeup, this); mpv_set_wakeup_callback(mpv, wakeup, this);
@ -210,10 +209,10 @@ MPVBackend::~MPVBackend()
Utils::SetDPMS(true); Utils::SetDPMS(true);
command("write-watch-later-config"); command("write-watch-later-config");
if (usedirect) { if (usedirect && mpv_gl_cb) {
mpv_opengl_cb_uninit_gl(mpv_gl_cb);
} else if (mpv_gl){
mpv_render_context_free(mpv_gl); mpv_render_context_free(mpv_gl);
} else {
mpv_opengl_cb_set_update_callback(mpv_gl_cb, NULL, NULL);
} }
mpv_terminate_destroy(mpv); mpv_terminate_destroy(mpv);
@ -269,172 +268,24 @@ MPVBackend::playerCommand(const Enums::Commands& cmd)
QVariant QVariant
MPVBackend::playerCommand(const Enums::Commands& cmd, const QVariant& args) MPVBackend::playerCommand(const Enums::Commands& cmd, const QVariant& args)
{ {
switch (cmd) { return MPVCommon::playerCommand(this, cmd, args);
case Enums::Commands::TogglePlayPause: {
command(QVariantList() << "cycle"
<< "pause");
break;
}
case Enums::Commands::ToggleMute: {
command(QVariantList() << "cycle"
<< "mute");
break;
}
case Enums::Commands::SetAudioDevice: {
setProperty("audio-device", args.toString());
break;
}
case Enums::Commands::SetVolume: {
command(QVariantList() << "set"
<< "volume" << args);
break;
}
case Enums::Commands::AddVolume: {
command(QVariantList() << "add"
<< "volume" << args);
break;
}
case Enums::Commands::AddSpeed: {
QString speedString =
QString::number(getProperty("speed").toDouble() + args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::SubtractSpeed: {
QString speedString =
QString::number(getProperty("speed").toDouble() - args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::ChangeSpeed: {
playerCommand(
Enums::Commands::SetSpeed,
QVariant(getProperty("speed").toDouble() * args.toDouble()));
break;
}
case Enums::Commands::SetSpeed: {
command(QVariantList() << "set"
<< "speed" << args.toString());
break;
}
case Enums::Commands::ToggleStats: {
command(QVariantList() << "script-binding"
<< "stats/display-stats-toggle");
break;
}
case Enums::Commands::NextAudioTrack: {
command(QVariantList() << "cycle"
<< "audio");
break;
}
case Enums::Commands::NextSubtitleTrack: {
command(QVariantList() << "cycle"
<< "sub");
break;
}
case Enums::Commands::NextVideoTrack: {
command(QVariantList() << "cycle"
<< "video");
break;
}
case Enums::Commands::PreviousPlaylistItem: {
command(QVariantList() << "playlist-prev");
break;
}
case Enums::Commands::NextPlaylistItem: {
command(QVariantList() << "playlist-next"
<< "force");
break;
}
case Enums::Commands::LoadFile: {
command(QVariantList() << "loadfile" << args);
break;
}
case Enums::Commands::AppendFile: {
command(QVariantList() << "loadfile" << args << "append-play");
break;
}
case Enums::Commands::Seek: {
command(QVariantList() << "seek" << args);
break;
}
case Enums::Commands::SeekAbsolute: {
command(QVariantList() << "seek" << args << "absolute");
break;
}
case Enums::Commands::ForwardFrame: {
command(QVariantList() << "frame-step");
break;
}
case Enums::Commands::BackwardFrame: {
command(QVariantList() << "frame-back-step");
break;
}
case Enums::Commands::SetTrack: {
command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
break;
}
case Enums::Commands::SetPlaylistPos: {
command(QVariantList() << "set"
<< "playlist-pos" << args);
break;
}
case Enums::Commands::ForcePause: {
command(QVariantList() << "set"
<< "pause"
<< "yes");
break;
}
default: {
qDebug() << "Command not found: " << cmd;
break;
}
}
return QVariant("NoOutput");
} }
QString
MPVBackend::getStats()
{
return MPVCommon::getStats(this);
}
void
MPVBackend::updateDurationString(int numTime)
{
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
MPVCommon::updateDurationString(this, numTime, metaMethod);
}
void void
MPVBackend::toggleOnTop() MPVBackend::toggleOnTop()
{ {
@ -463,335 +314,16 @@ MPVBackend::on_mpv_events()
} }
} }
void
MPVBackend::updateDurationString(int numTime)
{
QVariant speed = getProperty("speed");
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
if (metaMethod.name() == "positionChanged") {
if (speed != lastSpeed) {
lastSpeed = speed.toDouble();
} else {
if (numTime == lastTime) {
return;
}
}
lastTime = numTime;
lastPositionString = Utils::createTimestamp(lastTime);
} else if (metaMethod.name() == "durationChanged") {
totalDurationString = Utils::createTimestamp(numTime);
}
QString durationString;
durationString += lastPositionString;
durationString += " / ";
durationString += totalDurationString;
if (lastSpeed != 1) {
if (settings.value("Appearance/themeName", "").toString() !=
"RoosterTeeth") {
durationString += " (" + speed.toString() + "x)";
}
}
emit durationStringChanged(durationString);
}
QVariantMap QVariantMap
MPVBackend::getAudioDevices(const QVariant& drivers) const MPVBackend::getAudioDevices(const QVariant& drivers) const
{ {
QVariantMap newDrivers; return MPVCommon::getAudioDevices(drivers);
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
foreach (const QVariant& v, iterable) {
QVariantMap item = v.toMap();
newDrivers[item["description"].toString()] = item;
}
return newDrivers;
} }
void void
MPVBackend::handle_mpv_event(mpv_event* event) MPVBackend::handle_mpv_event(mpv_event* event)
{ {
switch (event->event_id) { MPVCommon::handle_mpv_event(this, event);
case MPV_EVENT_PROPERTY_CHANGE: {
mpv_event_property* prop = (mpv_event_property*)event->data;
if (strcmp(prop->name, "time-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit positionChanged(time);
}
} else if (strcmp(prop->name, "duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit durationChanged(time);
}
} else if (strcmp(prop->name, "mute") == 0 ||
strcmp(prop->name, "volume") == 0) {
double volume = getProperty("volume").toDouble();
bool mute = getProperty("mute").toBool();
if (mute || volume == 0) {
emit volumeStatusChanged(Enums::VolumeStatus::Muted);
} else {
if (volume < 25) {
emit volumeStatusChanged(Enums::VolumeStatus::Low);
} else {
emit volumeStatusChanged(Enums::VolumeStatus::Normal);
}
}
// emit volumeChanged(volume);
} else if (strcmp(prop->name, "media-title") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* title = *(char**)prop->data;
emit titleChanged(QString(title));
}
} else if (strcmp(prop->name, "sub-text") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* subs = *(char**)prop->data;
emit subtitlesChanged(QString(subs));
}
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double duration = *(double*)prop->data;
emit cachedDurationChanged(duration);
}
} else if (strcmp(prop->name, "playlist-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double pos = *(double*)prop->data;
emit playlistPositionChanged(pos);
}
} else if (strcmp(prop->name, "pause") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
if (mpv::qt::node_to_variant(nod).toBool()) {
emit playStatusChanged(Enums::PlayStatus::Paused);
// Utils::SetScreensaver(window()->winId(), true);
} else {
emit playStatusChanged(Enums::PlayStatus::Playing);
// Utils::SetScreensaver(window()->winId(), false);
}
} else if (strcmp(prop->name, "track-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit tracksChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "audio-device-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit audioDevicesChanged(
getAudioDevices(mpv::qt::node_to_variant(nod)));
} else if (strcmp(prop->name, "playlist") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit playlistChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "chapter-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit chaptersChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "speed") == 0) {
double speed = *(double*)prop->data;
emit speedChanged(speed);
}
break;
}
case MPV_EVENT_LOG_MESSAGE: {
if (m_logging) {
struct mpv_event_log_message* msg =
(struct mpv_event_log_message*)event->data;
QString logMsg = "[" + QString(msg->prefix) + "] " + QString(msg->text);
QString msgLevel = QString(msg->level);
if (msgLevel.startsWith("d") || msgLevel.startsWith("t")) {
mpvLogger->info("{}", logMsg.toStdString());
} else if (msgLevel.startsWith("v") || msgLevel.startsWith("i")) {
mpvLogger->info("{}", logMsg.toStdString());
} else {
mpvLogger->debug("{}", logMsg.toStdString());
}
}
break;
}
case MPV_EVENT_SHUTDOWN: {
qApp->exit();
break;
}
default: {
break;
}
}
}
QString
MPVBackend::getStats()
{
QString stats;
stats =
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
QString filename = getProperty("filename").toString();
// File Info
stats += "<b>File:</b> " + filename;
stats += "<blockquote>";
QString title = getProperty("media-title").toString();
if (title != filename) {
stats += "<b>Title:</b> " + title + "<br>";
}
QString fileFormat = getProperty("file-format").toString();
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
QLocale a;
// a.formattedDataSize(
double cacheUsed = getProperty("cache-used").toDouble();
// Utils::createTimestamp(
int demuxerSecs = getProperty("demuxer-cache-duration").toInt();
QVariantMap demuxerState = getProperty("demuxer-cache-state").toMap();
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
QString cacheStats;
cacheStats += "<b>Total Cache:</b> ";
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
cacheStats += " (<b>Demuxer:</b> ";
cacheStats += a.formattedDataSize(demuxerCache);
cacheStats += ", ";
cacheStats += QString::number(demuxerSecs) + "s) ";
double cacheSpeed = getProperty("cache-speed").toDouble();
if (cacheSpeed > 0) {
cacheStats += "<b>Speed:</b> ";
cacheStats += a.formattedDataSize(demuxerSecs);
cacheStats += "/s";
}
cacheStats += "<br>";
stats += cacheStats;
}
QString fileSize =
a.formattedDataSize(getProperty("file-size").toInt()).remove("-");
stats += "<b>Size:</b> " + fileSize + "<br>";
stats += "</blockquote>";
// Video Info
QVariant videoParams = getProperty("video-params");
if (videoParams.isNull()) {
videoParams = getProperty("video-out-params");
}
if (!videoParams.isNull()) {
stats += "<b>Video:</b> " + getProperty("video-codec").toString();
stats += "<blockquote>";
QString avsync = QString::number(getProperty("avsync").toDouble(), 'f', 3);
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
stats += "<b>Dropped Frames:</b> ";
int dFDC = getProperty("decoder-frame-drop-count").toInt();
if (dFDC > 0) {
stats += QString::number(dFDC) + " (decoder) ";
}
int fDC = getProperty("frame-drop-count").toInt();
if (fDC > 0) {
stats += QString::number(fDC) + " (output)";
}
stats += "<br>";
int dFPS = getProperty("display-fps").toInt();
int eDFPS = getProperty("estimated-display-fps").toInt();
if ((dFPS + eDFPS) > 0) {
stats += "<b>Display FPS:</b> ";
if (dFPS > 0) {
stats += QString::number(dFPS);
stats += " (specified) ";
}
if (eDFPS > 0) {
stats += QString::number(eDFPS);
stats += " (estimated)";
}
stats += "<br>";
}
int cFPS = getProperty("container-fps").toInt();
int eVFPS = getProperty("estimated-vf-fps").toInt();
if ((cFPS + eVFPS) > 0) {
stats += "<b>FPS:</b> ";
if (cFPS > 0) {
stats += QString::number(cFPS);
stats += " (specified) ";
}
if (eVFPS > 0) {
stats += QString::number(eVFPS);
stats += " (estimated)";
}
stats += "<br>";
}
QVariantMap vPM = videoParams.toMap();
stats += "<b>Native Resolution:</b> ";
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
stats += "<br>";
stats += "<b>Window Scale:</b> ";
stats += vPM["window-scale"].toString();
stats += "<br>";
stats += "<b>Aspect Ratio:</b> ";
stats += vPM["aspect"].toString();
stats += "<br>";
stats += "<b>Pixel Format:</b> ";
stats += vPM["pixelformat"].toString();
stats += "<br>";
stats += "<b>Primaries:</b> ";
stats += vPM["primaries"].toString();
stats += " <b>Colormatrix:</b> ";
stats += vPM["colormatrix"].toString();
stats += "<br>";
stats += "<b>Levels:</b> ";
stats += vPM["colorlevels"].toString();
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
if (sigPeak > 0) {
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
}
stats += "<br>";
stats += "<b>Gamma:</b> ";
stats += vPM["gamma"].toString();
stats += "<br>";
int pVB = getProperty("packet-video-bitrate").toInt();
if (pVB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pVB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
QVariant audioParams = getProperty("audio-params");
if (audioParams.isNull()) {
audioParams = getProperty("audio-out-params");
}
if (!audioParams.isNull()) {
stats += "<b>Audio:</b> " + getProperty("audio-codec").toString();
stats += "<blockquote>";
QVariantMap aPM = audioParams.toMap();
stats += "<b>Format:</b> ";
stats += aPM["format"].toString();
stats += "<br>";
stats += "<b>Sample Rate:</b> ";
stats += aPM["samplerate"].toString() + " Hz";
stats += "<br>";
stats += "<b>Channels:</b> ";
stats += aPM["chanel-count"].toString();
stats += "<br>";
int pAB = getProperty("packet-audio-bitrate").toInt();
if (pAB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pAB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
return stats;
} }
QQuickFramebufferObject::Renderer* QQuickFramebufferObject::Renderer*

View file

@ -15,8 +15,6 @@
#include "src/enums.hpp" #include "src/enums.hpp"
#include "src/utils.hpp" #include "src/utils.hpp"
extern bool usedirect;
class MpvRenderer; class MpvRenderer;
class MPVBackend class MPVBackend
@ -36,11 +34,6 @@ class MPVBackend
bool onTop = false; bool onTop = false;
bool m_logging = true; bool m_logging = true;
int lastTime = 0;
double lastSpeed = 0;
QString totalDurationString;
QString lastPositionString;
friend class MpvRenderer; friend class MpvRenderer;
public: public:
@ -58,6 +51,11 @@ public:
} }
bool logging() const { return m_logging; } bool logging() const { return m_logging; }
int lastTime = 0;
double lastSpeed = 0;
QString totalDurationString;
QString lastPositionString;
public slots: public slots:
QVariant playerCommand(const Enums::Commands& command, const QVariant& args); QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
QVariant playerCommand(const Enums::Commands& command); QVariant playerCommand(const Enums::Commands& command);

View file

@ -0,0 +1,504 @@
#include "src/Backends/MPVCommon/MPVCommon.hpp"
#include "src/utils.hpp"
#include <QSettings>
#include <mpv/qthelper.hpp>
#include "src/logger.h"
auto mpvLogger = initLogger("mpv");
namespace MPVCommon {
QString getStats(BackendInterface *b) {
QString stats;
stats =
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
QString filename = b->getProperty("filename").toString();
// File Info
stats += "<b>File:</b> " + filename;
stats += "<blockquote>";
QString title = b->getProperty("media-title").toString();
if (title != filename) {
stats += "<b>Title:</b> " + title + "<br>";
}
QString fileFormat = b->getProperty("file-format").toString();
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
QLocale a;
// a.formattedDataSize(
double cacheUsed = b->getProperty("cache-used").toDouble();
// Utils::createTimestamp(
int demuxerSecs = b->getProperty("demuxer-cache-duration").toInt();
QVariantMap demuxerState = b->getProperty("demuxer-cache-state").toMap();
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
QString cacheStats;
cacheStats += "<b>Total Cache:</b> ";
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
cacheStats += " (<b>Demuxer:</b> ";
cacheStats += a.formattedDataSize(demuxerCache);
cacheStats += ", ";
cacheStats += QString::number(demuxerSecs) + "s) ";
double cacheSpeed = b->getProperty("cache-speed").toDouble();
if (cacheSpeed > 0) {
cacheStats += "<b>Speed:</b> ";
cacheStats += a.formattedDataSize(demuxerSecs);
cacheStats += "/s";
}
cacheStats += "<br>";
stats += cacheStats;
}
QString fileSize =
a.formattedDataSize(b->getProperty("file-size").toInt()).remove("-");
stats += "<b>Size:</b> " + fileSize + "<br>";
stats += "</blockquote>";
// Video Info
QVariant videoParams = b->getProperty("video-params");
if (videoParams.isNull()) {
videoParams = b->getProperty("video-out-params");
}
if (!videoParams.isNull()) {
stats += "<b>Video:</b> " + b->getProperty("video-codec").toString();
stats += "<blockquote>";
QString avsync = QString::number(b->getProperty("avsync").toDouble(), 'f', 3);
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
stats += "<b>Dropped Frames:</b> ";
int dFDC = b->getProperty("decoder-frame-drop-count").toInt();
if (dFDC > 0) {
stats += QString::number(dFDC) + " (decoder) ";
}
int fDC = b->getProperty("frame-drop-count").toInt();
if (fDC > 0) {
stats += QString::number(fDC) + " (output)";
}
stats += "<br>";
int dFPS = b->getProperty("display-fps").toInt();
int eDFPS = b->getProperty("estimated-display-fps").toInt();
if ((dFPS + eDFPS) > 0) {
stats += "<b>Display FPS:</b> ";
if (dFPS > 0) {
stats += QString::number(dFPS);
stats += " (specified) ";
}
if (eDFPS > 0) {
stats += QString::number(eDFPS);
stats += " (estimated)";
}
stats += "<br>";
}
int cFPS = b->getProperty("container-fps").toInt();
int eVFPS = b->getProperty("estimated-vf-fps").toInt();
if ((cFPS + eVFPS) > 0) {
stats += "<b>FPS:</b> ";
if (cFPS > 0) {
stats += QString::number(cFPS);
stats += " (specified) ";
}
if (eVFPS > 0) {
stats += QString::number(eVFPS);
stats += " (estimated)";
}
stats += "<br>";
}
QVariantMap vPM = videoParams.toMap();
stats += "<b>Native Resolution:</b> ";
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
stats += "<br>";
stats += "<b>Window Scale:</b> ";
stats += vPM["window-scale"].toString();
stats += "<br>";
stats += "<b>Aspect Ratio:</b> ";
stats += vPM["aspect"].toString();
stats += "<br>";
stats += "<b>Pixel Format:</b> ";
stats += vPM["pixelformat"].toString();
stats += "<br>";
stats += "<b>Primaries:</b> ";
stats += vPM["primaries"].toString();
stats += " <b>Colormatrix:</b> ";
stats += vPM["colormatrix"].toString();
stats += "<br>";
stats += "<b>Levels:</b> ";
stats += vPM["colorlevels"].toString();
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
if (sigPeak > 0) {
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
}
stats += "<br>";
stats += "<b>Gamma:</b> ";
stats += vPM["gamma"].toString();
stats += "<br>";
int pVB = b->getProperty("packet-video-bitrate").toInt();
if (pVB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pVB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
QVariant audioParams = b->getProperty("audio-params");
if (audioParams.isNull()) {
audioParams = b->getProperty("audio-out-params");
}
if (!audioParams.isNull()) {
stats += "<b>Audio:</b> " + b->getProperty("audio-codec").toString();
stats += "<blockquote>";
QVariantMap aPM = audioParams.toMap();
stats += "<b>Format:</b> ";
stats += aPM["format"].toString();
stats += "<br>";
stats += "<b>Sample Rate:</b> ";
stats += aPM["samplerate"].toString() + " Hz";
stats += "<br>";
stats += "<b>Channels:</b> ";
stats += aPM["chanel-count"].toString();
stats += "<br>";
int pAB = b->getProperty("packet-audio-bitrate").toInt();
if (pAB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pAB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
return stats;
}
QVariant playerCommand(BackendInterface *b, const Enums::Commands& cmd, const QVariant& args)
{
switch (cmd) {
case Enums::Commands::TogglePlayPause: {
b->command(QVariantList() << "cycle"
<< "pause");
break;
}
case Enums::Commands::ToggleMute: {
b->command(QVariantList() << "cycle"
<< "mute");
break;
}
case Enums::Commands::SetAudioDevice: {
b->setProperty("audio-device", args.toString());
break;
}
case Enums::Commands::SetVolume: {
b->command(QVariantList() << "set"
<< "volume" << args);
break;
}
case Enums::Commands::AddVolume: {
b->command(QVariantList() << "add"
<< "volume" << args);
break;
}
case Enums::Commands::AddSpeed: {
QString speedString =
QString::number(b->getProperty("speed").toDouble() + args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
b->playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::SubtractSpeed: {
QString speedString =
QString::number(b->getProperty("speed").toDouble() - args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
b->playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::ChangeSpeed: {
b->playerCommand(
Enums::Commands::SetSpeed,
QVariant(b->getProperty("speed").toDouble() * args.toDouble()));
break;
}
case Enums::Commands::SetSpeed: {
b->command(QVariantList() << "set"
<< "speed" << args.toString());
break;
}
case Enums::Commands::ToggleStats: {
b->command(QVariantList() << "script-binding"
<< "stats/display-stats-toggle");
break;
}
case Enums::Commands::NextAudioTrack: {
b->command(QVariantList() << "cycle"
<< "audio");
break;
}
case Enums::Commands::NextSubtitleTrack: {
b->command(QVariantList() << "cycle"
<< "sub");
break;
}
case Enums::Commands::NextVideoTrack: {
b->command(QVariantList() << "cycle"
<< "video");
break;
}
case Enums::Commands::PreviousPlaylistItem: {
b->command(QVariantList() << "playlist-prev");
break;
}
case Enums::Commands::NextPlaylistItem: {
b->command(QVariantList() << "playlist-next"
<< "force");
break;
}
case Enums::Commands::LoadFile: {
b->command(QVariantList() << "loadfile" << args);
break;
}
case Enums::Commands::AppendFile: {
b->command(QVariantList() << "loadfile" << args << "append-play");
break;
}
case Enums::Commands::Seek: {
b->command(QVariantList() << "seek" << args);
break;
}
case Enums::Commands::SeekAbsolute: {
b->command(QVariantList() << "seek" << args << "absolute");
break;
}
case Enums::Commands::ForwardFrame: {
b->command(QVariantList() << "frame-step");
break;
}
case Enums::Commands::BackwardFrame: {
b->command(QVariantList() << "frame-back-step");
break;
}
case Enums::Commands::SetTrack: {
b->command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
break;
}
case Enums::Commands::SetPlaylistPos: {
b->command(QVariantList() << "set"
<< "playlist-pos" << args);
break;
}
case Enums::Commands::ForcePause: {
b->command(QVariantList() << "set"
<< "pause"
<< "yes");
break;
}
default: {
qDebug() << "Command not found: " << cmd;
break;
}
}
return QVariant("NoOutput");
}
void updateDurationString(BackendInterface *b, int numTime, QMetaMethod metaMethod)
{
QVariant speed = b->getProperty("speed");
QSettings settings;
if (metaMethod.name() == "positionChanged") {
if (speed != b->lastSpeed) {
b->lastSpeed = speed.toDouble();
} else {
if (numTime == b->lastTime) {
return;
}
}
b->lastTime = numTime;
b->lastPositionString = Utils::createTimestamp(b->lastTime);
} else if (metaMethod.name() == "durationChanged") {
b->totalDurationString = Utils::createTimestamp(numTime);
}
QString durationString;
durationString += b->lastPositionString;
durationString += " / ";
durationString += b->totalDurationString;
if (b->lastSpeed != 1) {
if (settings.value("Appearance/themeName", "").toString() !=
"RoosterTeeth") {
durationString += " (" + speed.toString() + "x)";
}
}
emit b->durationStringChanged(durationString);
}
void
handle_mpv_event(BackendInterface *b, mpv_event* event)
{
switch (event->event_id) {
case MPV_EVENT_PROPERTY_CHANGE: {
mpv_event_property* prop = (mpv_event_property*)event->data;
if (strcmp(prop->name, "time-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit b->positionChanged(time);
}
} else if (strcmp(prop->name, "duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit b->durationChanged(time);
}
} else if (strcmp(prop->name, "mute") == 0 ||
strcmp(prop->name, "volume") == 0) {
double volume = b->getProperty("volume").toDouble();
bool mute = b->getProperty("mute").toBool();
if (mute || volume == 0) {
emit b->volumeStatusChanged(Enums::VolumeStatus::Muted);
} else {
if (volume < 25) {
emit b->volumeStatusChanged(Enums::VolumeStatus::Low);
} else {
emit b->volumeStatusChanged(Enums::VolumeStatus::Normal);
}
}
// emit volumeChanged(volume);
} else if (strcmp(prop->name, "media-title") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* title = *(char**)prop->data;
emit b->titleChanged(QString(title));
}
} else if (strcmp(prop->name, "sub-text") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* subs = *(char**)prop->data;
emit b->subtitlesChanged(QString(subs));
}
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double duration = *(double*)prop->data;
emit b->cachedDurationChanged(duration);
}
} else if (strcmp(prop->name, "playlist-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double pos = *(double*)prop->data;
emit b->playlistPositionChanged(pos);
}
} else if (strcmp(prop->name, "pause") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
if (mpv::qt::node_to_variant(nod).toBool()) {
emit b->playStatusChanged(Enums::PlayStatus::Paused);
// Utils::SetScreensaver(window()->winId(), true);
} else {
emit b->playStatusChanged(Enums::PlayStatus::Playing);
// Utils::SetScreensaver(window()->winId(), false);
}
} else if (strcmp(prop->name, "track-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit b->tracksChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "audio-device-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit b->audioDevicesChanged(b->getAudioDevices(mpv::qt::node_to_variant(nod)));
} else if (strcmp(prop->name, "playlist") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit b->playlistChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "chapter-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit b->chaptersChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "speed") == 0) {
double speed = *(double*)prop->data;
emit b->speedChanged(speed);
}
break;
}
case MPV_EVENT_LOG_MESSAGE: {
struct mpv_event_log_message* msg =
(struct mpv_event_log_message*)event->data;
QString logMsg = "[" + QString(msg->prefix) + "] " + QString(msg->text);
QString msgLevel = QString(msg->level);
if (msgLevel.startsWith("d") || msgLevel.startsWith("t")) {
mpvLogger->info("{}", logMsg.toStdString());
} else if (msgLevel.startsWith("v") || msgLevel.startsWith("i")) {
mpvLogger->info("{}", logMsg.toStdString());
} else {
mpvLogger->debug("{}", logMsg.toStdString());
}
break;
}
case MPV_EVENT_SHUTDOWN: {
qApp->exit();
break;
}
default: {
break;
}
}
}
QVariantMap getAudioDevices(const QVariant& drivers)
{
QVariantMap newDrivers;
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
foreach (const QVariant& v, iterable) {
QVariantMap item = v.toMap();
newDrivers[item["description"].toString()] = item;
}
return newDrivers;
}
}

View file

@ -0,0 +1,19 @@
#ifndef MPVCommon_H
#define MPVCommon_H
#include <QString>
#include "src/backendinterface.hpp"
#include <mpv/client.h>
namespace MPVCommon {
QString getStats(BackendInterface *b);
QVariant playerCommand(BackendInterface *b, const Enums::Commands& cmd, const QVariant& args);
void updateDurationString(BackendInterface *b, int numTime, QMetaMethod metaMethod);
void handle_mpv_event(BackendInterface *b, mpv_event* event);
QVariantMap getAudioDevices(const QVariant& drivers);
}
#endif

View file

@ -14,6 +14,9 @@
#include <QSequentialIterable> #include <QSequentialIterable>
#include <math.h> #include <math.h>
#include "src/Backends/MPVCommon/MPVCommon.hpp"
void void
wakeup(void* ctx) wakeup(void* ctx)
{ {
@ -232,162 +235,7 @@ QVariant
MPVNoFBOBackend::playerCommand(const Enums::Commands& cmd, MPVNoFBOBackend::playerCommand(const Enums::Commands& cmd,
const QVariant& args) const QVariant& args)
{ {
switch (cmd) { return MPVCommon::playerCommand(this, cmd, args);
case Enums::Commands::TogglePlayPause: {
command(QVariantList() << "cycle"
<< "pause");
break;
}
case Enums::Commands::ToggleMute: {
command(QVariantList() << "cycle"
<< "mute");
break;
}
case Enums::Commands::SetAudioDevice: {
setProperty("audio-device", args.toString());
break;
}
case Enums::Commands::SetVolume: {
command(QVariantList() << "set"
<< "volume" << args);
break;
}
case Enums::Commands::AddVolume: {
command(QVariantList() << "add"
<< "volume" << args);
break;
}
case Enums::Commands::AddSpeed: {
QString speedString =
QString::number(getProperty("speed").toDouble() + args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::SubtractSpeed: {
QString speedString =
QString::number(getProperty("speed").toDouble() - args.toDouble());
QVariant newSpeed =
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
playerCommand(Enums::Commands::SetSpeed, newSpeed);
break;
}
case Enums::Commands::ChangeSpeed: {
playerCommand(
Enums::Commands::SetSpeed,
QVariant(getProperty("speed").toDouble() * args.toDouble()));
break;
}
case Enums::Commands::SetSpeed: {
command(QVariantList() << "set"
<< "speed" << args.toString());
break;
}
case Enums::Commands::ToggleStats: {
command(QVariantList() << "script-binding"
<< "stats/display-stats-toggle");
break;
}
case Enums::Commands::NextAudioTrack: {
command(QVariantList() << "cycle"
<< "audio");
break;
}
case Enums::Commands::NextSubtitleTrack: {
command(QVariantList() << "cycle"
<< "sub");
break;
}
case Enums::Commands::NextVideoTrack: {
command(QVariantList() << "cycle"
<< "video");
break;
}
case Enums::Commands::PreviousPlaylistItem: {
command(QVariantList() << "playlist-prev");
break;
}
case Enums::Commands::NextPlaylistItem: {
command(QVariantList() << "playlist-next"
<< "force");
break;
}
case Enums::Commands::LoadFile: {
command(QVariantList() << "loadfile" << args);
break;
}
case Enums::Commands::AppendFile: {
command(QVariantList() << "loadfile" << args << "append-play");
break;
}
case Enums::Commands::Seek: {
command(QVariantList() << "seek" << args);
break;
}
case Enums::Commands::SeekAbsolute: {
command(QVariantList() << "seek" << args << "absolute");
break;
}
case Enums::Commands::ForwardFrame: {
command(QVariantList() << "frame-step");
break;
}
case Enums::Commands::BackwardFrame: {
command(QVariantList() << "frame-back-step");
break;
}
case Enums::Commands::SetTrack: {
command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
break;
}
case Enums::Commands::SetPlaylistPos: {
command(QVariantList() << "set"
<< "playlist-pos" << args);
break;
}
default: {
qDebug() << "Command not found: " << cmd;
break;
}
}
return QVariant("NoOutput");
} }
void void
@ -444,322 +292,26 @@ MPVNoFBOBackend::on_mpv_events()
void void
MPVNoFBOBackend::updateDurationString(int numTime) MPVNoFBOBackend::updateDurationString(int numTime)
{ {
QVariant speed = getProperty("speed");
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex()); QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
if (metaMethod.name() == "positionChanged") { MPVCommon::updateDurationString(this, numTime, metaMethod);
if (speed != lastSpeed) {
lastSpeed = speed.toDouble();
} else {
if (numTime == lastTime) {
return;
}
}
lastTime = numTime;
lastPositionString = Utils::createTimestamp(lastTime);
} else if (metaMethod.name() == "durationChanged") {
totalDurationString = Utils::createTimestamp(numTime);
}
QString durationString;
durationString += lastPositionString;
durationString += " / ";
durationString += totalDurationString;
if (lastSpeed != 1) {
if (settings.value("Appearance/themeName", "").toString() !=
"RoosterTeeth") {
durationString += " (" + speed.toString() + "x)";
}
}
emit durationStringChanged(durationString);
} }
QVariantMap QVariantMap
MPVNoFBOBackend::getAudioDevices() const MPVNoFBOBackend::getAudioDevices(const QVariant& drivers) const
{ {
QVariant drivers = getProperty("audio-device-list"); return MPVCommon::getAudioDevices(drivers);
QVariant currentDevice = getProperty("audio-device");
QVariantMap newDrivers;
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
foreach (const QVariant& v, iterable) {
QVariantMap item = v.toMap();
item["selected"] = currentDevice == item["name"];
newDrivers[item["description"].toString()] = item;
}
QMap<QString, QVariant> pulseItem;
pulseItem["name"] = "pulse";
pulseItem["description"] = "Default (pulseaudio)";
pulseItem["selected"] = currentDevice == "pulse";
newDrivers[pulseItem["description"].toString()] = pulseItem;
return newDrivers;
} }
void void
MPVNoFBOBackend::handle_mpv_event(mpv_event* event) MPVNoFBOBackend::handle_mpv_event(mpv_event* event)
{ {
switch (event->event_id) { MPVCommon::handle_mpv_event(this, event);
case MPV_EVENT_PROPERTY_CHANGE: {
mpv_event_property* prop = (mpv_event_property*)event->data;
if (strcmp(prop->name, "time-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit positionChanged(time);
}
} else if (strcmp(prop->name, "duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double*)prop->data;
emit durationChanged(time);
}
} else if (strcmp(prop->name, "mute") == 0 ||
strcmp(prop->name, "volume") == 0) {
double volume = getProperty("volume").toDouble();
bool mute = getProperty("mute").toBool();
if (mute || volume == 0) {
emit volumeStatusChanged(Enums::VolumeStatus::Muted);
} else {
if (volume < 25) {
emit volumeStatusChanged(Enums::VolumeStatus::Low);
} else {
emit volumeStatusChanged(Enums::VolumeStatus::Normal);
}
}
// emit volumeChanged(volume);
} else if (strcmp(prop->name, "media-title") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* title = *(char**)prop->data;
emit titleChanged(QString(title));
}
} else if (strcmp(prop->name, "sub-text") == 0) {
if (prop->format == MPV_FORMAT_STRING) {
char* subs = *(char**)prop->data;
emit subtitlesChanged(QString(subs));
}
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double duration = *(double*)prop->data;
emit cachedDurationChanged(duration);
}
} else if (strcmp(prop->name, "playlist-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double pos = *(double*)prop->data;
emit playlistPositionChanged(pos);
}
} else if (strcmp(prop->name, "pause") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
if (mpv::qt::node_to_variant(nod).toBool()) {
emit playStatusChanged(Enums::PlayStatus::Paused);
Utils::SetScreensaver(window()->winId(), true);
} else {
emit playStatusChanged(Enums::PlayStatus::Playing);
Utils::SetScreensaver(window()->winId(), true);
}
} else if (strcmp(prop->name, "track-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit tracksChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "audio-device-list") == 0) {
emit audioDevicesChanged(getAudioDevices());
} else if (strcmp(prop->name, "playlist") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit playlistChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "chapter-list") == 0) {
mpv_node* nod = (mpv_node*)prop->data;
emit chaptersChanged(mpv::qt::node_to_variant(nod).toList());
} else if (strcmp(prop->name, "speed") == 0) {
double speed = *(double*)prop->data;
emit speedChanged(speed);
}
break;
}
case MPV_EVENT_SHUTDOWN: {
qApp->exit();
break;
}
default: {
break;
}
}
} }
QString QString
MPVNoFBOBackend::getStats() MPVNoFBOBackend::getStats()
{ {
QString stats; return MPVCommon::getStats(this);
stats =
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
QString filename = getProperty("filename").toString();
// File Info
stats += "<b>File:</b> " + filename;
stats += "<blockquote>";
QString title = getProperty("media-title").toString();
if (title != filename) {
stats += "<b>Title:</b> " + title + "<br>";
}
QString fileFormat = getProperty("file-format").toString();
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
QLocale a;
// a.formattedDataSize(
double cacheUsed = getProperty("cache-used").toDouble();
// Utils::createTimestamp(
int demuxerSecs = getProperty("demuxer-cache-duration").toInt();
QVariantMap demuxerState = getProperty("demuxer-cache-state").toMap();
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
QString cacheStats;
cacheStats += "<b>Total Cache:</b> ";
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
cacheStats += " (<b>Demuxer:</b> ";
cacheStats += a.formattedDataSize(demuxerCache);
cacheStats += ", ";
cacheStats += QString::number(demuxerSecs) + "s) ";
double cacheSpeed = getProperty("cache-speed").toDouble();
if (cacheSpeed > 0) {
cacheStats += "<b>Speed:</b> ";
cacheStats += a.formattedDataSize(demuxerSecs);
cacheStats += "/s";
}
cacheStats += "<br>";
stats += cacheStats;
}
QString fileSize =
a.formattedDataSize(getProperty("file-size").toInt()).remove("-");
stats += "<b>Size:</b> " + fileSize + "<br>";
stats += "</blockquote>";
// Video Info
QVariant videoParams = getProperty("video-params");
if (videoParams.isNull()) {
videoParams = getProperty("video-out-params");
}
if (!videoParams.isNull()) {
stats += "<b>Video:</b> " + getProperty("video-codec").toString();
stats += "<blockquote>";
QString avsync = QString::number(getProperty("avsync").toDouble(), 'f', 3);
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
stats += "<b>Dropped Frames:</b> ";
int dFDC = getProperty("decoder-frame-drop-count").toInt();
if (dFDC > 0) {
stats += QString::number(dFDC) + " (decoder) ";
}
int fDC = getProperty("frame-drop-count").toInt();
if (fDC > 0) {
stats += QString::number(fDC) + " (output)";
}
stats += "<br>";
int dFPS = getProperty("display-fps").toInt();
int eDFPS = getProperty("estimated-display-fps").toInt();
if ((dFPS + eDFPS) > 0) {
stats += "<b>Display FPS:</b> ";
if (dFPS > 0) {
stats += QString::number(dFPS);
stats += " (specified) ";
}
if (eDFPS > 0) {
stats += QString::number(eDFPS);
stats += " (estimated)";
}
stats += "<br>";
}
int cFPS = getProperty("container-fps").toInt();
int eVFPS = getProperty("estimated-vf-fps").toInt();
if ((cFPS + eVFPS) > 0) {
stats += "<b>FPS:</b> ";
if (cFPS > 0) {
stats += QString::number(cFPS);
stats += " (specified) ";
}
if (eVFPS > 0) {
stats += QString::number(eVFPS);
stats += " (estimated)";
}
stats += "<br>";
}
QVariantMap vPM = videoParams.toMap();
stats += "<b>Native Resolution:</b> ";
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
stats += "<br>";
stats += "<b>Window Scale:</b> ";
stats += vPM["window-scale"].toString();
stats += "<br>";
stats += "<b>Aspect Ratio:</b> ";
stats += vPM["aspect"].toString();
stats += "<br>";
stats += "<b>Pixel Format:</b> ";
stats += vPM["pixelformat"].toString();
stats += "<br>";
stats += "<b>Primaries:</b> ";
stats += vPM["primaries"].toString();
stats += " <b>Colormatrix:</b> ";
stats += vPM["colormatrix"].toString();
stats += "<br>";
stats += "<b>Levels:</b> ";
stats += vPM["colorlevels"].toString();
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
if (sigPeak > 0) {
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
}
stats += "<br>";
stats += "<b>Gamma:</b> ";
stats += vPM["gamma"].toString();
stats += "<br>";
int pVB = getProperty("packet-video-bitrate").toInt();
if (pVB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pVB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
QVariant audioParams = getProperty("audio-params");
if (audioParams.isNull()) {
audioParams = getProperty("audio-out-params");
}
if (!audioParams.isNull()) {
stats += "<b>Audio:</b> " + getProperty("audio-codec").toString();
stats += "<blockquote>";
QVariantMap aPM = audioParams.toMap();
stats += "<b>Format:</b> ";
stats += aPM["format"].toString();
stats += "<br>";
stats += "<b>Sample Rate:</b> ";
stats += aPM["samplerate"].toString() + " Hz";
stats += "<br>";
stats += "<b>Channels:</b> ";
stats += aPM["chanel-count"].toString();
stats += "<br>";
int pAB = getProperty("packet-audio-bitrate").toInt();
if (pAB > 0) {
stats += "<b>Bitrate:</b> ";
stats += a.formattedDataSize(pAB) + "/s";
stats += "<br>";
}
stats += "</blockquote>";
}
return stats;
} }

View file

@ -44,11 +44,7 @@ class MPVNoFBOBackend
mpv_opengl_cb_context* mpv_gl; mpv_opengl_cb_context* mpv_gl;
MPVNoFBORenderer* renderer; MPVNoFBORenderer* renderer;
bool onTop = false; bool onTop = false;
int lastTime = 0;
double lastSpeed = 0;
bool m_logging = true; bool m_logging = true;
QString totalDurationString;
QString lastPositionString;
QSettings settings; QSettings settings;
public: public:
@ -65,6 +61,11 @@ public:
MPVNoFBOBackend(QQuickItem* parent = 0); MPVNoFBOBackend(QQuickItem* parent = 0);
virtual ~MPVNoFBOBackend(); virtual ~MPVNoFBOBackend();
int lastTime = 0;
double lastSpeed = 0;
QString totalDurationString;
QString lastPositionString;
public slots: public slots:
QVariant playerCommand(const Enums::Commands& command, const QVariant& args); QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
QVariant playerCommand(const Enums::Commands& command); QVariant playerCommand(const Enums::Commands& command);
@ -82,7 +83,9 @@ public slots:
void cleanup(); void cleanup();
// Just used for adding missing audio devices to list. // Just used for adding missing audio devices to list.
QVariantMap getAudioDevices() const; QVariantMap getAudioDevices(const QVariant& drivers) const;
bool event(QEvent* event); bool event(QEvent* event);
signals: signals:

View file

@ -11,6 +11,10 @@ class BackendInterface
{ {
public: public:
virtual ~BackendInterface(){}; virtual ~BackendInterface(){};
int lastTime = 0;
double lastSpeed = 0;
QString totalDurationString;
QString lastPositionString;
public slots: public slots:
// All 5 required for Player API // All 5 required for Player API
@ -23,6 +27,8 @@ public slots:
virtual void setProperty(const QString& name, const QVariant& value) = 0; virtual void setProperty(const QString& name, const QVariant& value) = 0;
virtual void setOption(const QString& name, const QVariant& value) = 0; virtual void setOption(const QString& name, const QVariant& value) = 0;
virtual QVariant getProperty(const QString& name) const = 0; virtual QVariant getProperty(const QString& name) const = 0;
virtual QVariantMap getAudioDevices(const QVariant& drivers) const = 0;
signals: signals:
// All below required for Player API // All below required for Player API

View file

@ -52,7 +52,8 @@ Window {
id: backendSettings id: backendSettings
category: "Backend" category: "Backend"
property string backend: "mpv" property string backend: "mpv"
property bool checkForUpdatesOnLaunch: true property bool fbo: true
property bool direct: false
} }
Settings { Settings {

View file

@ -14,7 +14,7 @@
#include <QtCore> #include <QtCore>
#include <QtNetwork> #include <QtNetwork>
#ifdef __linux__ #if defined(__linux__) || defined(__FreeBSD__)
#ifdef ENABLE_X11 #ifdef ENABLE_X11
#include <QX11Info> #include <QX11Info>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -83,7 +83,7 @@ SetScreensaver(WId wid, bool on)
void void
SetDPMS(bool on) SetDPMS(bool on)
{ {
#ifdef __linux__ #if defined(__linux__) || defined(__FreeBSD__)
if (getPlatformName() != "xcb") { if (getPlatformName() != "xcb") {
return; return;
} }
@ -112,13 +112,13 @@ SetDPMS(bool on)
void void
AlwaysOnTop(WId wid, bool on) AlwaysOnTop(WId wid, bool on)
{ {
#ifdef __linux__ #if defined(__linux__) || defined(__FreeBSD__)
#ifdef ENABLE_X11 #ifdef ENABLE_X11
Display* display = QX11Info::display(); Display* display = QX11Info::display();
XEvent event; XEvent event;
event.xclient.type = ClientMessage; event.xclient.type = ClientMessage;
event.xclient.serial = 0; event.xclient.serial = 0;
event.xclient.send_event = True; event.xclient.send_event = true;
event.xclient.display = display; event.xclient.display = display;
event.xclient.window = wid; event.xclient.window = wid;
event.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False); event.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False);