aboutsummaryrefslogtreecommitdiff
path: root/visualization/renderer/qmpvisrendercore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'visualization/renderer/qmpvisrendercore.cpp')
-rw-r--r--visualization/renderer/qmpvisrendercore.cpp463
1 files changed, 236 insertions, 227 deletions
diff --git a/visualization/renderer/qmpvisrendercore.cpp b/visualization/renderer/qmpvisrendercore.cpp
index b12ed91..9d58206 100644
--- a/visualization/renderer/qmpvisrendercore.cpp
+++ b/visualization/renderer/qmpvisrendercore.cpp
@@ -19,262 +19,271 @@
#include <QCommandLineParser>
#include <QDebug>
#include <QThread>
-qmpVisRenderCore *qmpVisRenderCore::inst=nullptr;
+qmpVisRenderCore *qmpVisRenderCore::inst = nullptr;
-qmpVisRenderCore::qmpVisRenderCore(QCommandLineParser *_clp):QObject(nullptr),clp(_clp)
+qmpVisRenderCore::qmpVisRenderCore(QCommandLineParser *_clp): QObject(nullptr), clp(_clp)
{
- inst=this;
- player=new CMidiPlayer();
- api=new qmpPluginAPIStub(this);
- msettings=new qmpSettingsRO();
- frameno=0;
- msettings->registerOptionEnumInt("MIDI","Text encoding","Midi/TextEncoding",{"Unicode","Big5","Big5-HKSCS","CP949","EUC-JP","EUC-KR","GB18030","KOI8-R","KOI8-U","Macintosh","Shift-JIS"},0);
+ inst = this;
+ player = new CMidiPlayer();
+ api = new qmpPluginAPIStub(this);
+ msettings = new qmpSettingsRO();
+ frameno = 0;
+ msettings->registerOptionEnumInt("MIDI", "Text encoding", "Midi/TextEncoding", {"Unicode", "Big5", "Big5-HKSCS", "CP949", "EUC-JP", "EUC-KR", "GB18030", "KOI8-R", "KOI8-U", "Macintosh", "Shift-JIS"}, 0);
}
bool qmpVisRenderCore::loadVisualizationLibrary()
{
#ifdef _WIN32
- std::vector<std::wstring> libpath={
- QCoreApplication::applicationDirPath().toStdWString()+L"/plugins/libvisualization.dll",
- L"libvisualization.dll",
- L"../libvisualization.dll"//for debugging only...?
- };
+ std::vector<std::wstring> libpath =
+ {
+ QCoreApplication::applicationDirPath().toStdWString() + L"/plugins/libvisualization.dll",
+ L"libvisualization.dll",
+ L"../libvisualization.dll"//for debugging only...?
+ };
#else
- std::vector<std::string> libpath={
- QCoreApplication::applicationDirPath().toStdString()+"/plugins/libvisualization.so",
- QT_STRINGIFY(INSTALL_PREFIX)+std::string("/lib/qmidiplayer/libvisualization.so"),
- "../libvisualization.so"//for debugging only
- };
+ std::vector<std::string> libpath =
+ {
+ QCoreApplication::applicationDirPath().toStdString() + "/plugins/libvisualization.so",
+ QT_STRINGIFY(INSTALL_PREFIX) + std::string("/lib/qmidiplayer/libvisualization.so"),
+ "../libvisualization.so"//for debugging only
+ };
#endif
- for(auto&l:libpath)
- {
- mp=dlopen(l.c_str(),RTLD_LAZY);
- if(mp)break;
- }
- if(!mp)
- {
- fprintf(stderr,"failed to load the visualization module!\n");
- return false;
- }
- GetInterface_func getintf=reinterpret_cast<GetInterface_func>(dlsym(mp,"qmpPluginGetInterface"));
- SwitchMode_func switchmode=reinterpret_cast<SwitchMode_func>(dlsym(mp,"switchToRenderMode"));
- vf=nullptr;
- vp=getintf(api);
- switchmode(&qmpVisRenderCore::framefunc,!clp->isSet("show-window"));
- vp->init();
- resetcb(nullptr,nullptr);
- if(clp->isSet("list-options"))
- {
- msettings->listopt();
- exit(0);
- }
- return true;
+ for (auto &l : libpath)
+ {
+ mp = dlopen(l.c_str(), RTLD_LAZY);
+ if (mp)
+ break;
+ }
+ if (!mp)
+ {
+ fprintf(stderr, "failed to load the visualization module!\n");
+ return false;
+ }
+ GetInterface_func getintf = reinterpret_cast<GetInterface_func>(dlsym(mp, "qmpPluginGetInterface"));
+ SwitchMode_func switchmode = reinterpret_cast<SwitchMode_func>(dlsym(mp, "switchToRenderMode"));
+ vf = nullptr;
+ vp = getintf(api);
+ switchmode(&qmpVisRenderCore::framefunc, !clp->isSet("show-window"));
+ vp->init();
+ resetcb(nullptr, nullptr);
+ if (clp->isSet("list-options"))
+ {
+ msettings->listopt();
+ exit(0);
+ }
+ return true;
}
void qmpVisRenderCore::unloadVisualizationLibrary()
{
- vp->deinit();
- dlclose(mp);
+ vp->deinit();
+ dlclose(mp);
}
void qmpVisRenderCore::loadSettings()
{
- if(clp->isSet("config"))
- msettings->load(clp->value("config").toStdString().c_str());
- for(auto &o:clp->values("option"))
- {
- int sp=o.indexOf('=');
- if(!~sp)
- {
- qDebug("invalid option pair: %s",o.toStdString().c_str());
- continue;
- }
- QString key=o.left(sp);
- QString value=o.mid(sp+1);
- msettings->setopt(key.toStdString(),value.toStdString());
- }
+ if (clp->isSet("config"))
+ msettings->load(clp->value("config").toStdString().c_str());
+ for (auto &o : clp->values("option"))
+ {
+ int sp = o.indexOf('=');
+ if (!~sp)
+ {
+ qDebug("invalid option pair: %s", o.toStdString().c_str());
+ continue;
+ }
+ QString key = o.left(sp);
+ QString value = o.mid(sp + 1);
+ msettings->setopt(key.toStdString(), value.toStdString());
+ }
}
void qmpVisRenderCore::setMIDIFile(const char *url)
{
- player->playerLoadFile(url);
+ player->playerLoadFile(url);
}
void qmpVisRenderCore::startRender()
{
- assert(vf);
- subst={
- {'w',QString::number(msettings->getOptionInt("Visualization/wwidth"))},
- {'h',QString::number(msettings->getOptionInt("Visualization/wheight"))},
- {'r',QString::number(msettings->getOptionInt("Visualization/tfps"))},
- {'i',
- QStringList()
- <<"-f"<<"rawvideo"
- <<"-pixel_format"<<"rgba"
- <<"-video_size"<<QString("%1x%2").arg(msettings->getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight"))
- <<"-framerate"<<QString::number(msettings->getOptionInt("Visualization/tfps"))
- <<"-i"<<"pipe:"
- },
- {'o',clp->value("output-file")}
- };
- if(clp->value("receiver-execution")=="per-frame")
- {
- subst['o']=clp->value("output-file").replace("%f",QString("%1").arg(frameno,6,10,QChar('0')));
- oneshot=false;
- }
- else
- {
- oneshot=true;
- if(clp->value("receiver-execution")!="one-shot")
- qWarning("Invalid value set for --receiver-execution. Using default value.");
- }
- rxproc=new QProcess();
- QStringList arguments=process_arguments(clp->value("receiver"),subst);
- assert(arguments.length()>0);
- rxproc->setProgram(arguments.front());
- arguments.pop_front();
- rxproc->setArguments(arguments);
- frameconn=connect(this,&qmpVisRenderCore::frameRendered,this,
- [this](void* px,size_t sz,uint32_t c,uint32_t t)
- {
- if(sz)
- {
- if(!oneshot)
- {
- subst['f']=QString("%1").arg(frameno,6,10,QChar('0'));
- subst['o']=clp->value("output-file").replace("%f",QString("%1").arg(frameno,6,10,QChar('0')));
- frameno++;
- QStringList arguments=process_arguments(clp->value("receiver"),subst);
- arguments.pop_front();
- rxproc->setArguments(arguments);
- rxproc->start();
- rxproc->waitForStarted();
- }
- if(!rxproc->isOpen())return;
- rxproc->write(static_cast<const char*>(px),static_cast<qint64>(sz));
- while(rxproc->bytesToWrite()>(oneshot?(1<<26):0))
- rxproc->waitForBytesWritten();
- if(!oneshot)
- {
- rxproc->closeWriteChannel();
- rxproc->waitForFinished(-1);
- }
- }
- fprintf(stderr,"Rendered tick %u of %u, %.2f%% done.\r",c,t,std::min(100.,100.*c/t));
- if(c>t)
- {
- this->rxproc->closeWriteChannel();
- disconnect(frameconn);
- qApp->exit(0);
- }
- },Qt::ConnectionType::BlockingQueuedConnection);
- connect(rxproc,QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished),
- [this](int x,QProcess::ExitStatus st){
- qDebug("%s",this->rxproc->readAllStandardError().data());
- if(oneshot)
- {
- disconnect(frameconn);
- if(x||st==QProcess::ExitStatus::CrashExit)
- qApp->exit(1);
- else
- qApp->exit(0);
- }
- });
- QMetaObject::invokeMethod(this,[this](){
- if(oneshot)
- rxproc->start();
- vf->show();
- startcb(nullptr,nullptr);
- },Qt::ConnectionType::QueuedConnection);
+ assert(vf);
+ subst =
+ {
+ {'w', QString::number(msettings->getOptionInt("Visualization/wwidth"))},
+ {'h', QString::number(msettings->getOptionInt("Visualization/wheight"))},
+ {'r', QString::number(msettings->getOptionInt("Visualization/tfps"))},
+ {
+ 'i',
+ QStringList()
+ << "-f" << "rawvideo"
+ << "-pixel_format" << "rgba"
+ << "-video_size" << QString("%1x%2").arg(msettings->getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight"))
+ << "-framerate" << QString::number(msettings->getOptionInt("Visualization/tfps"))
+ << "-i" << "pipe:"
+ },
+ {'o', clp->value("output-file")}
+ };
+ if (clp->value("receiver-execution") == "per-frame")
+ {
+ subst['o'] = clp->value("output-file").replace("%f", QString("%1").arg(frameno, 6, 10, QChar('0')));
+ oneshot = false;
+ }
+ else
+ {
+ oneshot = true;
+ if (clp->value("receiver-execution") != "one-shot")
+ qWarning("Invalid value set for --receiver-execution. Using default value.");
+ }
+ rxproc = new QProcess();
+ QStringList arguments = process_arguments(clp->value("receiver"), subst);
+ assert(arguments.length() > 0);
+ rxproc->setProgram(arguments.front());
+ arguments.pop_front();
+ rxproc->setArguments(arguments);
+ frameconn = connect(this, &qmpVisRenderCore::frameRendered, this,
+ [this](void *px, size_t sz, uint32_t c, uint32_t t)
+ {
+ if (sz)
+ {
+ if (!oneshot)
+ {
+ subst['f'] = QString("%1").arg(frameno, 6, 10, QChar('0'));
+ subst['o'] = clp->value("output-file").replace("%f", QString("%1").arg(frameno, 6, 10, QChar('0')));
+ frameno++;
+ QStringList arguments = process_arguments(clp->value("receiver"), subst);
+ arguments.pop_front();
+ rxproc->setArguments(arguments);
+ rxproc->start();
+ rxproc->waitForStarted();
+ }
+ if (!rxproc->isOpen())
+ return;
+ rxproc->write(static_cast<const char *>(px), static_cast<qint64>(sz));
+ while (rxproc->bytesToWrite() > (oneshot ? (1 << 26) : 0))
+ rxproc->waitForBytesWritten();
+ if (!oneshot)
+ {
+ rxproc->closeWriteChannel();
+ rxproc->waitForFinished(-1);
+ }
+ }
+ fprintf(stderr, "Rendered tick %u of %u, %.2f%% done.\r", c, t, std::min(100., 100.*c / t));
+ if (c > t)
+ {
+ this->rxproc->closeWriteChannel();
+ disconnect(frameconn);
+ qApp->exit(0);
+ }
+ }, Qt::ConnectionType::BlockingQueuedConnection);
+ connect(rxproc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ [this](int x, QProcess::ExitStatus st)
+ {
+ qDebug("%s", this->rxproc->readAllStandardError().data());
+ if (oneshot)
+ {
+ disconnect(frameconn);
+ if (x || st == QProcess::ExitStatus::CrashExit)
+ qApp->exit(1);
+ else
+ qApp->exit(0);
+ }
+ });
+ QMetaObject::invokeMethod(this, [this]()
+ {
+ if (oneshot)
+ rxproc->start();
+ vf->show();
+ startcb(nullptr, nullptr);
+ }, Qt::ConnectionType::QueuedConnection);
}
-QStringList qmpVisRenderCore::process_arguments(QString a,QMap<QChar,QVariant> subst)
+QStringList qmpVisRenderCore::process_arguments(QString a, QMap<QChar, QVariant> subst)
{
- QStringList ret;
- QString buf;
- bool escaped=false;
- bool substi=false;
- for(int i=0;i<a.length();++i)
- {
- if(a[i]=='%')
- {
- if(escaped)
- {
- buf+='%';
- escaped=false;
- }
- else if(substi)
- {
- buf+='%';
- substi=false;
- }
- else substi=true;
- }
- else if(a[i]=='\\')
- {
- if(substi)
- {
- buf+='%';
- substi=false;
- }
- if(escaped)
- {
- buf+='\\';
- escaped=false;
- }
- else escaped=true;
- }
- else if(a[i]==' ')
- {
- if(substi)
- {
- buf+='%';
- substi=false;
- }
- if(escaped)buf+=' ';
- else
- {
- if(buf.length())
- ret.append(buf);
- buf.clear();
- }
- escaped=false;
- }
- else
- {
- if(substi&&subst.contains(a[i]))
- {
- if(subst[a[i]].canConvert(QMetaType::QString))
- buf+=subst[a[i]].toString();
- else
- {
- if(buf.length())
- {
- ret.append(buf);
- buf.clear();
- }
- for(auto &it:subst[a[i]].toStringList())
- ret.append(it);
- }
- substi=false;
- }
- else
- {
- if(escaped)
- {
- buf+='\\';
- escaped=false;
- }
- buf+=a[i];
- }
- }
- }
- if(buf.length())
- ret.append(buf);
- return ret;
+ QStringList ret;
+ QString buf;
+ bool escaped = false;
+ bool substi = false;
+ for (int i = 0; i < a.length(); ++i)
+ {
+ if (a[i] == '%')
+ {
+ if (escaped)
+ {
+ buf += '%';
+ escaped = false;
+ }
+ else if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ else substi = true;
+ }
+ else if (a[i] == '\\')
+ {
+ if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ if (escaped)
+ {
+ buf += '\\';
+ escaped = false;
+ }
+ else escaped = true;
+ }
+ else if (a[i] == ' ')
+ {
+ if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ if (escaped)
+ buf += ' ';
+ else
+ {
+ if (buf.length())
+ ret.append(buf);
+ buf.clear();
+ }
+ escaped = false;
+ }
+ else
+ {
+ if (substi && subst.contains(a[i]))
+ {
+ if (subst[a[i]].canConvert(QMetaType::QString))
+ buf += subst[a[i]].toString();
+ else
+ {
+ if (buf.length())
+ {
+ ret.append(buf);
+ buf.clear();
+ }
+ for (auto &it : subst[a[i]].toStringList())
+ ret.append(it);
+ }
+ substi = false;
+ }
+ else
+ {
+ if (escaped)
+ {
+ buf += '\\';
+ escaped = false;
+ }
+ buf += a[i];
+ }
+ }
+ }
+ if (buf.length())
+ ret.append(buf);
+ return ret;
}
-void qmpVisRenderCore::framefunc(void *px, size_t sz,uint32_t curf,uint32_t totf)
+void qmpVisRenderCore::framefunc(void *px, size_t sz, uint32_t curf, uint32_t totf)
{
- emit inst->frameRendered(px,sz,curf,totf);
+ emit inst->frameRendered(px, sz, curf, totf);
}