From f4f80b19a27118275d5f925558f3cfb46bb5d14b Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sat, 2 May 2020 00:57:43 +0800 Subject: Reworked parameter passing for the frame processor program. --- visualization/renderer/qmpvisrendercore.cpp | 159 +++++++++++++++++++++------- 1 file changed, 122 insertions(+), 37 deletions(-) (limited to 'visualization/renderer/qmpvisrendercore.cpp') diff --git a/visualization/renderer/qmpvisrendercore.cpp b/visualization/renderer/qmpvisrendercore.cpp index d4acea9..304d061 100644 --- a/visualization/renderer/qmpvisrendercore.cpp +++ b/visualization/renderer/qmpvisrendercore.cpp @@ -4,6 +4,7 @@ #include "qmpmidiplay.hpp" #include "qmpcorepublic.hpp" +#include #include #include @@ -19,6 +20,7 @@ qmpVisRenderCore::qmpVisRenderCore(QCommandLineParser *_clp):QObject(nullptr),cl 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); } @@ -72,62 +74,120 @@ void qmpVisRenderCore::setMIDIFile(const char *url) void qmpVisRenderCore::startRender() { assert(vf); - ffmpegproc=new QProcess(); - ffmpegproc->setProgram("ffmpeg"); - QStringList arguments; - arguments.append(split_arguments(clp->value("ffmpeg-pre-args"))); - arguments - <<"-f"<<"rawvideo" - <<"-pixel_format"<<"rgba" - <<"-video_size"<getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight")) - <<"-framerate"<getOptionInt("Visualization/tfps")) - <<"-i"<<"pipe:"; - arguments.append(split_arguments(clp->value("ffmpeg-args"))); - arguments<value("output-file"); - ffmpegproc->setArguments(arguments); - QMetaObject::Connection frameconn=connect(this,&qmpVisRenderCore::frameRendered,this, - [this,&frameconn](void* px,size_t sz,uint32_t c,uint32_t t) + 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"<getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight")) + <<"-framerate"<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(!ffmpegproc->isOpen())return; - ffmpegproc->write(static_cast(px),static_cast(sz)); - while(ffmpegproc->bytesToWrite()>1<<26) - ffmpegproc->waitForBytesWritten(); + 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(px),static_cast(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,100.*c/t); + fprintf(stderr,"Rendered tick %u of %u, %.2f%% done.\r",c,t,std::min(100.,100.*c/t)); if(c>t) { - this->ffmpegproc->closeWriteChannel(); + this->rxproc->closeWriteChannel(); disconnect(frameconn); qApp->exit(0); } },Qt::ConnectionType::BlockingQueuedConnection); - connect(ffmpegproc,QOverload::of(&QProcess::finished), - [this,&frameconn](int x,QProcess::ExitStatus st){ - qDebug("%s",this->ffmpegproc->readAllStandardError().data()); - disconnect(frameconn); - if(x||st==QProcess::ExitStatus::CrashExit) - qApp->exit(1); - else - qApp->exit(0); + connect(rxproc,QOverload::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](){ - ffmpegproc->start(); + if(oneshot) + rxproc->start(); vf->show(); startcb(nullptr,nullptr); },Qt::ConnectionType::QueuedConnection); } -QStringList qmpVisRenderCore::split_arguments(QString a) +QStringList qmpVisRenderCore::process_arguments(QString a,QMap subst) { QStringList ret; QString buf; bool escaped=false; + bool substi=false; for(int i=0;i