aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2020-05-02 10:42:01 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2020-05-02 10:42:01 +0800
commit86f10fa1bcdc25bf4a91e9b07322edcaa885fe49 (patch)
tree4a73e85ed4bce11edc4639d67444749c8f153ff5
parentf4f80b19a27118275d5f925558f3cfb46bb5d14b (diff)
downloadQMidiPlayer-86f10fa1bcdc25bf4a91e9b07322edcaa885fe49.tar.xz
New command line option "list-options" for visualization renderer.
Add documentation for the visualization renderer.
-rw-r--r--doc/visualization.html118
-rw-r--r--visualization/renderer/main.cpp5
-rw-r--r--visualization/renderer/qmpsettingsro.cpp52
-rw-r--r--visualization/renderer/qmpsettingsro.hpp1
-rw-r--r--visualization/renderer/qmpvisrendercore.cpp5
5 files changed, 178 insertions, 3 deletions
diff --git a/doc/visualization.html b/doc/visualization.html
index 6ad44dd..207d3a5 100644
--- a/doc/visualization.html
+++ b/doc/visualization.html
@@ -69,7 +69,7 @@
<li>Enable VSync: Enable vertical synchronization.</li>
<li>Save Viewport: Restore last camera configuration when the visualization is started.</li>
<li>Window Width/Height: Change the window size. If the size equals to your screen size, the visualization will start in fullscreen mode.</li>
- <li>FPS: FPS limit of the visualization.</li>
+ <li>Target FPS: FPS limit of the visualization.</li>
<li>Supersampling: Supersample anti-aliasing for the 3D visualization scene. 1 means no SSAA.</li>
<li>Multisampling: Multisample anti-aliasing for the 3D visualization scene. 0 means no MSAA.</li>
<li>FOV: Field of view.</li>
@@ -87,6 +87,122 @@
</ul>
</li>
</ul>
+ <h2>Visualization Renderer</h2>
+ The visualization plugin comes with a standalone application that generates high quality rendering of a midi file.
+ <h3>Command line usage</h3>
+ <pre style="font-variant-ligatures:none;">
+Usage: ./qmpvisrender [options] file
+Renderer a visualization of a midi file.
+
+Options:
+ -h, --help Displays help on commandline options.
+ --help-all Displays help including Qt specific options.
+ -v, --version Displays version information.
+ -f, --output-file &lt;filename&gt; File name of the output file.
+ --receiver &lt;command&gt; Specify a program and its arguments to
+ process the rendered frames. Supports
+ parameter substitution. See documentation for
+ details.
+ -e, --receiver-execution &lt;mode&gt; Execution mode of the receiver command.
+ Valid options are 'one-shot' and 'per-frame'
+ -s, --show-window Do not hide the visualization window.
+ -c, --config &lt;qmprc file&gt; Load options from the configuration file.
+ -o, --option &lt;key-value pair&gt; Set option for the visualization module.
+ --list-options Show a list of recognized options.
+
+Arguments:
+ file MIDI file to render
+ </pre>
+ <h3>Basic usage</h3>
+ You will most likely to load your QMidiPlayer configuration file so that
+ you can get the exact same results as viewed in QMidiPlayer.
+ You should also make sure ffmpeg is ready to use. Then you can run
+ <code>qmpvisrender -c &lt;path-to-configuration-file&gt; &lt;MIDI file to render&gt;</code>
+ and wait for the results. The output file is named output.mp4 and will be found
+ in the current work directory.
+ <h3>Supplementary materials for commandline options</h3>
+ <p>
+ When specifying a value for an option under the "Visualization" category, the category part
+ in the key may be omitted, so "-o Visualization/wwidth=1920" would become "-o wwidth=1920".
+ </p>
+ <p>
+ The renderer performs parameter substitution before invoking the receiver command line.
+ </p>
+ <table>
+ <style>
+ td,th{
+ padding-top:0.5em;
+ padding-bottom:0.5em;
+ }
+ </style>
+ <tr><th>Placeholder</th><th>Substituted with</th><th>Remarks</th></tr>
+ <tr><td><code>%w</code></td><td>width of an output frame in pixels</td><td></td></tr>
+ <tr><td><code>%h</code></td><td>height of an output frame in pixels</td><td></td></tr>
+ <tr><td><code>%r</code></td><td>framerate which the output frames should be played at</td><td></td></tr>
+ <tr><td><code>%i</code></td><td>input format specification for ffmpeg</td><td>shorthand for "-f rawvideo -pixel_format rgba -video_size %wx%h -framerate %r -i pipe:"</td></tr>
+ <tr><td><code>%o</code></td><td>output file name specified by the --output-file option</td><td>If the receiver execution mode is "per-frame", "%f" in the output file name will also be replaced.</td></tr>
+ <tr><td><code>%f</code></td><td>a six-digit frame number</td><td>only works if the receiver execution mode is "per-frame".</td></tr>
+ </table>
+ <p>
+ To add a literal space in the receiver command, put a single backslash before the space.
+ To add a percent sign, either put two consecutive percent signs or use a backslash followed
+ by a percent sign.
+ </p>
+ <p>
+ The default receiver command is <code>ffmpeg %i -vf vflip -pix_fmt yuv420p -c:v libx264 -preset slow -crf 22 %o</code>.
+ In case the output quality doesn't satisfy your needs, consider lowering the number after '-crf' or selecting a even slower
+ profile ('slower' or 'veryslow').
+ </p>
+ <h3>How it works</h3>
+ <p>
+ Notice: you don't have to understand anything under this section to use this tool.
+ You may try out the examples below or simply adhere to the basic usage shown above even this
+ section makes zero sense to you.
+ </p>
+ <p>
+ The renderer feeds a sequence of images into one command or a series of commands that process
+ the images through a pipe. That's it!
+ </p>
+ <p>
+ The data is an stream of raw RGBA values, where each color takes one byte in every pixel. The frame
+ size is the same as used by the visualization module, and the frames should be played back at a fixed
+ frame rate. The pixel data starts from the bottom-left of a frame and follows row-major ordering (so
+ you may want to flip the frame when using the frame with some applications).
+ </p>
+ <p>
+ The renderer supports two modes of receiver program operation. If the mode is set to 'one-shot',
+ the receiver is only started once and gets all rendered frames. If it is set to 'per-frame',
+ the receiver will be started every time a frame is rendered, and will only get one frame to process.
+ </p>
+ <h3>Examples</h3>
+ <p>
+ If you wish to try these examples, make sure you have the required receiver program ready to run.
+ </p>
+ <ol>
+ <li>Render to a vp9 encoded webm video.</li>
+ <pre style="white-space:pre-wrap;">
+qmpvisrender -c ~/.config/qmprc --output-file test.webm --receiver 'ffmpeg %i -vf vflip -c:v libvpx-vp9 -crf 30 -b:v 0 %o' &lt;midi file&gt;
+ </pre>
+ <li>Render to a h264 encoded mp4 video with hardware encoding acceleration using VA-API.</li>
+ <pre style="white-space:pre-wrap;">
+qmpvisrender -c ~/.config/qmprc --output-file test.mp4 --receiver 'ffmpeg -vaapi_device /dev/dri/renderD128 %i -vf vflip,format=nv12,hwupload -c:v h264_vaapi -b:v 5M %o' &lt;midi file&gt;
+ </pre>
+ <li>Render the frames into png files using imagemagick.</li>
+ <pre style="white-space:pre-wrap;">
+qmpvisrender -c ~/.config/qmprc --receiver-execution per-frame --receiver 'convert -size %wx%h -depth 8 RGBA:- -flip pngout/%f.png' &lt;midi file&gt;
+ </pre>
+ <li>Show the visualization window. Discard all rendered frames.</li>
+ <pre style="white-space:pre-wrap;">
+qmpvisrender -c ~/.config/qmprc -s --receiver 'dd of=/dev/null bs=24M' &lt;midi file&gt;
+ </pre>
+ <li>Save the raw frame data.</li>
+ <pre style="white-space:pre-wrap;">
+qmpvisrender -c ~/.config/qmprc --receiver-execution per-frame --receiver 'tee rawoutput/%f.raw' &lt;midi file&gt;
+ </pre>
+ </ol>
+ <h3>Useful stuff to refer to</h3>
+ <a target="_blank" href="https://www.ffmpeg.org/ffmpeg.html">ffmpeg documentation</a>
+ and <a target="_blank" href="https://www.ffmpeg.org/ffmpeg-codecs.html">ffmpeg codecs documentation</a>, if you want to tweak the ffmpeg encoder.
</div>
</body>
</html>
diff --git a/visualization/renderer/main.cpp b/visualization/renderer/main.cpp
index 82e8983..c651c54 100644
--- a/visualization/renderer/main.cpp
+++ b/visualization/renderer/main.cpp
@@ -18,7 +18,7 @@ int main(int argc,char **argv)
"receiver",
"Specify a program and its arguments to process the rendered frames. Supports parameter substitution. See documentation for details.",
"command",
- "ffmpeg -f rawvideo -pixel_format rgba -video_size %wx%h -framerate %r -i pipe: -vf vflip -pix_fmt yuv420p -c:v libx264 -preset slow -crf 22 %o"
+ "ffmpeg %i -vf vflip -pix_fmt yuv420p -c:v libx264 -preset slow -crf 22 %o"
});
clp.addOption({
{"e","receiver-execution"},
@@ -29,10 +29,11 @@ int main(int argc,char **argv)
clp.addOption({{"s","show-window"},"Do not hide the visualization window."});
clp.addOption({{"c","config"},"Load options from the configuration file.","qmprc file"});
clp.addOption({{"o","option"},"Set option for the visualization module.","key-value pair"});
+ clp.addOption({"list-options","Show a list of recognized options and quit."});
clp.addPositionalArgument("file","MIDI file to render");
clp.process(a.arguments());
qmpVisRenderCore core(&clp);
- if(clp.positionalArguments().empty())
+ if(clp.positionalArguments().empty()&&!clp.isSet("list-options"))
clp.showHelp(1);
core.loadSettings();
if(!core.loadVisualizationLibrary())
diff --git a/visualization/renderer/qmpsettingsro.cpp b/visualization/renderer/qmpsettingsro.cpp
index bf8096f..034f073 100644
--- a/visualization/renderer/qmpsettingsro.cpp
+++ b/visualization/renderer/qmpsettingsro.cpp
@@ -1,6 +1,8 @@
#include <QScopedPointer>
#include <QSettings>
+#include <cstdio>
+
#include "qmpsettingsro.hpp"
qmpSettingsRO::qmpSettingsRO()
@@ -172,3 +174,53 @@ void qmpSettingsRO::setopt(std::string key, std::string val)
if(key.find("Visualization/")!=0)
settings.insert("Visualization/"+QString(key.c_str()),QString(val.c_str()));
}
+
+void qmpSettingsRO::listopt()
+{
+ for(auto&k:optionlist)
+ {
+ printf("Option key: %s\n",k.c_str());
+ if(options[k].desc.length())
+ printf("Description: %s\n",options[k].desc.c_str());
+ switch(options[k].type)
+ {
+ case qmpOptionR::ParameterType::parameter_int:
+ printf("Type: int\n");
+ printf("Range: [%d,%d]\n",options[k].minv.toInt(),options[k].maxv.toInt());
+ printf("Default value: %d\n",options[k].defaultval.toInt());
+ break;
+ case qmpOptionR::ParameterType::parameter_uint:
+ printf("Type: uint\n");
+ printf("Range: [%u,%u]\n",options[k].minv.toUInt(),options[k].maxv.toUInt());
+ printf("Default value: %u\n",options[k].defaultval.toUInt());
+ break;
+ case qmpOptionR::ParameterType::parameter_double:
+ printf("Type: double\n");
+ printf("Range: [%.2f,%.2f]\n",options[k].minv.toDouble(),options[k].maxv.toDouble());
+ printf("Default value: %.f2\n",options[k].defaultval.toDouble());
+ break;
+ case qmpOptionR::ParameterType::parameter_bool:
+ printf("Type: bool\n");
+ printf("Default value: %s\n",options[k].defaultval.toBool()?"true":"false");
+ break;
+ case qmpOptionR::ParameterType::parameter_str:
+ printf("Type: str\n");
+ printf("Default value: %s\n",options[k].defaultval.toString().toStdString().c_str());
+ break;
+ case qmpOptionR::ParameterType::parameter_url:
+ printf("Type: url\n");
+ printf("Default value: %s\n",options[k].defaultval.toString().toStdString().c_str());
+ break;
+ case qmpOptionR::ParameterType::parameter_enum:
+ printf("Type: enum\n");
+ printf("Possible values: ");
+ for(size_t i=0;i<options[k].enumlist.size();++i)
+ printf("%s%s",options[k].enumlist[i].c_str(),i==options[k].enumlist.size()-1?"\n":", ");
+ printf("Default value: %s\n",options[k].enumlist[options[k].defaultval.toInt()].c_str());
+ break;
+ default:
+ printf("Type: unknown\n");
+ }
+ puts("");
+ }
+}
diff --git a/visualization/renderer/qmpsettingsro.hpp b/visualization/renderer/qmpsettingsro.hpp
index 5c5361d..c5dd8af 100644
--- a/visualization/renderer/qmpsettingsro.hpp
+++ b/visualization/renderer/qmpsettingsro.hpp
@@ -65,6 +65,7 @@ public:
void load(const char* path);
void setopt(std::string key,std::string val);
+ void listopt();
private:
std::map<std::string,qmpOptionR> options;
std::vector<std::string> optionlist;
diff --git a/visualization/renderer/qmpvisrendercore.cpp b/visualization/renderer/qmpvisrendercore.cpp
index 304d061..f8044f5 100644
--- a/visualization/renderer/qmpvisrendercore.cpp
+++ b/visualization/renderer/qmpvisrendercore.cpp
@@ -39,6 +39,11 @@ bool qmpVisRenderCore::loadVisualizationLibrary()
switchmode(&qmpVisRenderCore::framefunc,!clp->isSet("show-window"));
vp->init();
resetcb(nullptr,nullptr);
+ if(clp->isSet("list-options"))
+ {
+ msettings->listopt();
+ exit(0);
+ }
return true;
}