summaryrefslogtreecommitdiffstats
path: root/tools/qmlviewer
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmlviewer')
-rw-r--r--tools/qmlviewer/main.cpp18
-rw-r--r--tools/qmlviewer/qmlviewer.cpp138
-rw-r--r--tools/qmlviewer/qmlviewer.h3
3 files changed, 114 insertions, 45 deletions
diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp
index c5676ab..26ff213 100644
--- a/tools/qmlviewer/main.cpp
+++ b/tools/qmlviewer/main.cpp
@@ -27,11 +27,15 @@ void usage()
qWarning(" -v, -version ............................. display version");
qWarning(" -frameless ............................... run with no window frame");
qWarning(" -skin <qvfbskindir> ...................... run with a skin window frame");
- qWarning(" -recorddither ordered|threshold|floyd .... set dither mode used for recording");
+ qWarning(" -recordfile <output> ..................... set output file");
+ qWarning(" - ImageMagick 'convert' for GIF)");
+ qWarning(" - png file for raw frames");
+ qWarning(" - 'ffmpeg' for other formats");
+ qWarning(" -recorddither ordered|threshold|floyd .... set GIF dither recording mode");
qWarning(" -recordperiod <milliseconds> ............. set time between recording frames");
- qWarning(" -autorecord [from-]<tomilliseconds> ...... set recording to start and stop automatically");
+ qWarning(" -autorecord [from-]<tomilliseconds> ...... set recording to start and stop");
qWarning(" -devicekeys .............................. use numeric keys (see F1)");
- qWarning(" -cache ................................... enable a disk cache of remote content");
+ qWarning(" -cache ................................... disk cache remote content");
qWarning(" -recordtest <directory> .................. record an autotest");
qWarning(" -runtest <directory> ..................... run a previously recorded test");
qWarning(" ");
@@ -66,7 +70,8 @@ int main(int argc, char ** argv)
int period = 0;
int autorecord_from = 0;
int autorecord_to = 0;
- QString dither = "threshold";
+ QString dither = "none";
+ QString recordfile = "animation.gif";
QString skin;
bool devkeys = false;
bool cache = false;
@@ -83,6 +88,10 @@ int main(int argc, char ** argv)
cache = true;
} else if (arg == "-recordperiod") {
period = QString(argv[++i]).toInt();
+ } else if (arg == "-recordfile") {
+ recordfile = QString(argv[++i]);
+ } else if (arg == "-recorddither") {
+ dither = QString(argv[++i]);
} else if (arg == "-autorecord") {
QString range = QString(argv[++i]);
int dash = range.indexOf('-');
@@ -119,6 +128,7 @@ int main(int argc, char ** argv)
QmlViewer viewer(testMode, testDir, 0, frameless ? Qt::FramelessWindowHint : Qt::Widget);
viewer.setCacheEnabled(cache);
viewer.openQml(fileName);
+ viewer.setRecordFile(recordfile);
if (period>0)
viewer.setRecordPeriod(period);
if (autorecord_to)
diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp
index 00cb7f1..094d779 100644
--- a/tools/qmlviewer/qmlviewer.cpp
+++ b/tools/qmlviewer/qmlviewer.cpp
@@ -35,7 +35,7 @@
#include <QMenu>
QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, QWidget *parent, Qt::WindowFlags flags)
- : QWidget(parent, flags)
+ : QWidget(parent, flags), frame_stream(0)
{
testEngine = 0;
devicemode = false;
@@ -218,6 +218,11 @@ void QmlViewer::setAutoRecord(int from, int to)
}
}
+void QmlViewer::setRecordFile(const QString& f)
+{
+ record_file = f;
+}
+
void QmlViewer::setRecordPeriod(int ms)
{
record_period = ms;
@@ -246,7 +251,7 @@ void QmlViewer::keyPressEvent(QKeyEvent *event)
exit(0);
else if (event->key() == Qt::Key_F1 || (event->key() == Qt::Key_1 && devicemode)) {
qDebug() << "F1 - help\n"
- << "F2 - toggle GIF recording\n"
+ << "F2 - toggle video recording\n"
<< "F3 - take PNG snapshot\n"
<< "F4 - show items and state\n"
<< "F5 - reload QML\n"
@@ -288,49 +293,95 @@ void QmlViewer::setRecording(bool on)
if (on) {
recordTimer.start(record_period,this);
+ QString fmt = record_file.right(4).toLower();
+ if (fmt != ".png" && fmt != ".gif") {
+ // Stream video to ffmpeg
+
+ QProcess *proc = new QProcess(this);
+ frame_stream = proc;
+
+ QStringList args;
+ args << "-sameq"; // ie. high
+ args << "-y";
+ args << "-r" << QString::number(1000/record_period);
+ args << "-f" << "rawvideo";
+ args << "-pix_fmt" << "rgb32";
+ args << "-s" << QString("%1x%2").arg(canvas->width()).arg(canvas->height());
+ args << "-i" << "-";
+ args << record_file;
+ proc->start("ffmpeg",args,QIODevice::WriteOnly);
+ } else {
+ // Store frames, save to GIF/PNG
+ frame_stream = 0;
+ }
} else {
recordTimer.stop();
- int frame=0;
- QStringList inputs;
- qDebug() << "Saving frames...";
-
- foreach (QImage* img, frames) {
- QString name;
- name.sprintf("tmp-frame%04d.png",frame++);
- if (record_dither=="ordered")
- img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::OrderedDither).save(name);
- else if (record_dither=="threshold")
- img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::ThresholdDither).save(name);
- else if (record_dither=="floyd")
- img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither).save(name);
- else
- img->convertToFormat(QImage::Format_Indexed8).save(name);
- inputs << name;
- delete img;
- }
- QString output="animation.gif";
-
- QStringList args;
-
- args << "-delay" << QString::number(record_period/10);
- args << inputs;
- args << output;
- qDebug() << "Converting..." << output;
- if (0!=QProcess::execute("convert", args)) {
- qWarning() << "Cannot run ImageMagick 'convert' - not converted to gif";
- inputs.clear(); // don't remove them
- qDebug() << "Wrote frames tmp-frame*.png";
+ if (frame_stream) {
+ qDebug() << "Saving video...";
+ frame_stream->close();
+ qDebug() << "Wrote" << record_file;
} else {
- qDebug() << "Compressing..." << output;
- if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << output << output))
- qWarning() << "Cannot run 'gifsicle' - not compressed";
- qDebug() << "Wrote" << output;
- }
+ int frame=0;
+ QStringList inputs;
+ qDebug() << "Saving frames...";
+
+ QString framename;
+ bool png_output = false;
+ if (record_file.right(4).toLower()==".png") {
+ if (record_file.contains('%'))
+ framename = record_file;
+ else
+ framename = record_file.left(record_file.length()-4)+"%04d"+record_file.right(4);
+ png_output = true;
+ } else {
+ framename = "tmp-frame%04d.png";
+ png_output = false;
+ }
+ foreach (QImage* img, frames) {
+ QString name;
+ name.sprintf(framename.toLocal8Bit(),frame++);
+ if (record_dither=="ordered")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::OrderedDither).save(name);
+ else if (record_dither=="threshold")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::ThresholdDither).save(name);
+ else if (record_dither=="floyd")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither).save(name);
+ else
+ img->save(name);
+ inputs << name;
+ delete img;
+ }
+
+ if (png_output) {
+ framename.replace(QRegExp("%\\d*."),"*");
+ qDebug() << "Wrote frames" << framename;
+ inputs.clear(); // don't remove them
+ } else {
+ // ImageMagick and gifsicle for GIF encoding
+ QStringList args;
+ args << "-delay" << QString::number(record_period/10);
+ args << inputs;
+ args << record_file;
+ qDebug() << "Converting..." << record_file;
+ if (0!=QProcess::execute("convert", args)) {
+ qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted";
+ inputs.clear(); // don't remove them
+ qDebug() << "Wrote frames tmp-frame*.png";
+ } else {
+ if (record_file.right(4).toLower() == ".gif") {
+ qDebug() << "Compressing..." << record_file;
+ if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file))
+ qWarning() << "Cannot run 'gifsicle' - not compressed";
+ }
+ qDebug() << "Wrote" << record_file;
+ }
+ }
- foreach (QString name, inputs)
- QFile::remove(name);
+ foreach (QString name, inputs)
+ QFile::remove(name);
- frames.clear();
+ frames.clear();
+ }
}
qDebug() << "Recording: " << (recordTimer.isActive()?"ON":"OFF");
}
@@ -338,7 +389,12 @@ void QmlViewer::setRecording(bool on)
void QmlViewer::timerEvent(QTimerEvent *event)
{
if (event->timerId() == recordTimer.timerId()) {
- frames.append(new QImage(canvas->asImage()));
+ if (frame_stream) {
+ QImage frame(canvas->asImage());
+ frame_stream->write((char*)frame.bits(),frame.numBytes());
+ } else {
+ frames.append(new QImage(canvas->asImage()));
+ }
if (record_autotime && autoTimer.elapsed() >= record_autotime)
setRecording(false);
} else if (event->timerId() == autoStartTimer.timerId()) {
diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h
index 0fa879d..fc65ebf 100644
--- a/tools/qmlviewer/qmlviewer.h
+++ b/tools/qmlviewer/qmlviewer.h
@@ -33,6 +33,7 @@ public:
void setRecordDither(const QString& s) { record_dither = s; }
void setRecordPeriod(int ms);
+ void setRecordFile(const QString&);
int recordPeriod() const { return record_period; }
void setRecording(bool on);
bool isRecording() const { return recordTimer.isActive(); }
@@ -59,9 +60,11 @@ private:
void init(QFxTestEngine::TestMode, const QString &, const QString& fileName);
QBasicTimer recordTimer;
QList<QImage*> frames;
+ QIODevice* frame_stream;
QBasicTimer autoStartTimer;
QTime autoTimer;
QString record_dither;
+ QString record_file;
int record_period;
int record_autotime;
bool devicemode;