diff options
Diffstat (limited to 'visualization/renderer/qmpvisrendercore.cpp')
-rw-r--r-- | visualization/renderer/qmpvisrendercore.cpp | 463 |
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); } |