Qt: Taking screenshot of EGLFS window - pixel-perfect identical result? - qt

We're using EGLFS to run a QML app on an embedded linux device without a X server. So I can't use the usual techniques for getting a screenshot (e.g. using a screenshot utility app). In this question I found the technique of using QQuickView::grabWindow().
My question: Is the result of this function guaranteed to be pixel-perfect identical to what the user sees on the screen? I'm worried that to grab the window contents, Qt might have to rerender the window using a different code path (e.g. render-to-texture), which may cause results to differ.
I'd like a reliable reference included in your answers, too.

As far as I can tell, the screenshot is not going to be identical. Follow the code from QQuickWindow::grabWindow: it ends up calling qt_gl_read_framebuffer, which is always going to read the image out as RGB(A)8. Your actual framebuffer might be different (for instance, it could be RGB565).
(I also seem to remember that one cannot use RGBA reading via glReadPixels out of a RGB565 framebuffer, but I am not 100% sure that's true in all OpenGL versions/variants...)
Depending on your drivers, a workaround could be reading /dev/fb0 contents. Anyhow, please file a bug report if you need this functionality.

Related

SYCL DPC++ auto detect device

This question might be trivial, unfortunately I haven't found the answer I was looking for.
I used dpct migration tool to port some cuda code to Intel DPC++ and then I further optimized everything I needed and eventually got rid of everything related to dpct expect the super handy
dpct::get_current_device();
which basically solves all the previous pain I had to put compile options to select the appropriate device and control them with Makefiles and so on.
Is there any way to do this without using dpct ?
I had a look at how dpct does this (here) but it looks pretty non-straightforward and it relies on other internal functions.
Is there any way to avoid this ?
I'm not totally clear from your question whether you want to 1) grab a handle to your device or 2) select a device on which to run stuff, so I'll try to answer both. Note that dpct::get_current_device() isn't actually selecting a device, it's just returning the device which you have already selected earlier in your program.
Typically when using SYCL we start with a sycl::queue, which we use to submit kernels, memory copy operations etc. From a sycl::queue you can access your device with:
sycl::device d = q.get_device();
But it seems like you may instead be asking for the simplest way to select a device. In this case, the simplest approach is to construct your queue with one of SYCL's provided device selectors:
sycl::queue q{sycl::gpu_selector()};
sycl::queue q{sycl::cpu_selector()};
sycl::queue q{sycl::default_selector()};
Note that the last option (sycl::default_selector()) is probably what dpct is currently doing for you.

KDE Taskbar Progress

I am trying to show a progress in the taskbar of the plasma desktop using the KDE Frameworks. In short, it want to do the same thing as dolphin, when it copies files:
I'm kinda stuck, because I don't even know where to get started. The only thing I found that could be useful is KStatusBarJobTracker, but I don't know how to use it. I could not find any tutorials or examples how to do this.
So, after digging around, and thanks to the help of #leinir, I was able to find out the following:
Since Plasma 5.6 KDE supports the Unitiy DBus Launcher-API, which can be used, for example, to show progress
I found a post on AskUbuntu that explains how to use the API with Qt
The real problem is: This only works, if you have a valid desktop file in one of the standard locations! You need to pass the file as parameter of the DBus message to make it work.
Based on this information, I figured out how to use it and created a GitHub repository, that supports cross platform taskbar progress, and uses this API for the linux implementation.
However, here is how to do it anyways. It should work for KDE Plasma and the Unity desktop, maybe more (haven't tried any others):
Create a .desktop file for your application. For test purpose, this can be a "dummy" file, that could look like this:
[Desktop Entry]
Type=Application
Version=1.1
Name=MyApp
Exec=<path_to>/MyApp
Copy that file to ~/.local/share/applications/ (or wherever user specific desktop files go on your system)
In your code, all you need to do is execute the following code, to update the taskbar state:
auto message = QDBusMessage::createSignal(QStringLiteral("/com/example/MyApp"),
QStringLiteral("com.canonical.Unity.LauncherEntry"),
QStringLiteral("Update"));
//you don't always have to specify all parameters, just the ones you want to update
QVariantMap properties;
properties.insert(QStringLiteral("progress-visible"), true);// enable the progress
properties.insert(QStringLiteral("progress"), 0.5);// set the progress value (from 0.0 to 1.0)
properties.insert(QStringLiteral("count-visible"), true);// display the "counter badge"
properties.insert(QStringLiteral("count"), 42);// set the counter value
message << QStringLiteral("application://myapp.desktop") //assuming you named the desktop file "myapp.desktop"
<< properties;
QDBusConnection::sessionBus().send(message);
Compile and run your application. You don't have to start it via the desktop file, at least I did not need to. If you want to be sure your application is "connected" to that desktop file, just set a custom icon for the file. Your application should show that icon in the taskbar.
And thats basically it. Note: The system remembers the last state when restarting the application. Thus, you should reset all those parameters once when starting the application.
Right, so as it turns out you are right, there is not currently a tutorial for this. This reviewboard request, however, shows how it was implemented in KDevelop, and it should be possible for you to work it out through that :) https://git.reviewboard.kde.org/r/127050/
ps: that there is no tutorial now might be a nice way for you to hop in and help out, by writing a small, self contained tutorial for it... something i'm sure would be very much welcomed :)

Generating a waveform from an audio (or video) file?

I'm trying to understand how I can generate a waveform from an audio (or video) file to display to the user.
I've been googling around for quite a while now and can't determine if this is even possible in Qt without using something like FFmpeg. I've seen all of these classes: QMediaPlayer, QMediaContent, QMediaResource, QAudioProbe and experimented with the Qt Media Player Example but am just not seeing where I can access the actual audio buffer.
So I have 2 questions:
Is what I want to do even possible without 3rd party libraries?
If it is possible, can some kind soul outline what I need to read and understand in order to access the audio data
I have tried the suggestions from this question (Audio visualization with QMediaPlayer) but the result of audioProbe->setSource(player) is always false and the method processBuffer never gets called.
audioProbe = new QAudioProbe(this);
bool success = audioProbe->setSource(player);
qDebug() << success;
connect(audioProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
Update: Adding some additional detail in the hope of clarifying things.
For testing/learning I am using the Media Player Example which ships with Qt, so it is set up correctly with Q_OBJECT etc.
For audio, I tested with both .mp3 and .wav files. FWIW, the player example won't play video for some reason (.mp4, .avi were tested)
The player in the code is QMediaPlayer – which inherits from QMediaObject. The example code for the Player class is here. I added my code (in original comment above) right after the player is instantiated. I also tried adding it once media is loaded.
I tried declaring my slot first as private, then as public – either way, it is never called.
Frustrating that such a simple thing is so hard.
Going the "no external library" route will likely just lead to more of a headache and more work than is necessary. The other advantage of going with an established library is you won't be bound to one file format, as not all formats store their data the same way. If the audio format is uncompressed (wav or other) you can read the header until you get to the data chunk. An answer to this question here details this in C. You should be able to get an idea for the file format from this to apply it to another language.
You will want to understand how many channels are in the wav file, bit depth, and also the sampling rate before you can do anything worthwhile with the data. All this info can be grabbed from the header.
It turns out that QAudioProbe is not supported on OSX – the platform I am working on. Took quite a while (a "Qt while. . .") to ferret that info out so I am posting it here explicitly.
See this document for full details: Qt 5.5.0 Multimedia Backends

qtwebkit qt5 beta webgl

I was trying to run WebGL application on QtWebKit (Qt 5.0 beta Version). I am using eglfs plugin on a mips based platform. I used QtTestBrowser as the test browser.
I ran an webgl site-
./QtTestBrowser -webgl -graphicsbased http://jsbin.com/ulazel
It reported no-webgl support.
I did a bit of debugging and found that in file
qtwebkit/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp
it returns as it cannot find glViewport:
QGLWidget* glViewport = qobject_cast<QGLWidget*>(scrollArea->viewport());
if (!glViewport) {
//Returns from here....
return;
}
By enabling “-gl-viewport” I was able to get the glContext in HTML page. But it was not properly displayed. Also since every widget (launcherWindow etc) it was trying to create a “Window” intern calling eglCreateWindow() and resulting in memory issues (Around 12 window was created all full size of 1920×1080. Finally the displayed image is also not proper.
Any one have suggestion? where i am going wrong?
WebGL is functional with additional patches on top of Qt5. You might want to take a look at the patchset for WebGL for eglfs, at the below link.
https://bugreports.qt-project.org/browse/QTBUG-30405
(Note - I have validated this only on ARMv7, but I cannot see a dependency on arch for this patchset)

How to Add assertion in monkey runner

I need to add couple of assertions on the screen.
Lets Say I am on Page 1. I need to verify that some xxx text is displayed or not and button is displayed or not and also need to verify that the label of the button.
Please Help me how to add assertion in the monkey runner script..
Thanks
AFAIK Monkeyrunner doesn't have its own assertion mechanisms that would suit your need.
You can take a snapshot of your device and use some external image processing mechanism to verify interesting parts - but I know that wouldn't be ideal for text comparison.
You can use Python Imaging Library http://www.pythonware.com/products/pil/
Take a look at http://developer.android.com/guide/developing/tools/MonkeyImage.html, if you already have a MonkeyImage object that looks correct you can use MonkeyImage.sameAs() to compare it to the current MonkeyImage.
http://docs.python.org/library/pickle.html might be helpful for saving MonkeyImage objects. (I'd like to stress the might though)
The next version of the SDK should have a method of loading MonkeyImage objects from image files so you can compare it with less work. See https://review.source.android.com//#change,21478 for more info about this change.

Resources