mcallegari / qlcplus

Q Light Controller Plus (QLC+) is a free and cross-platform software to control DMX or analog lighting systems like moving heads, dimmers, scanners etc. This project is a fork of the great QLC project written by Heikki Junnila that aims to continue the QLC development and to introduce new features.
Apache License 2.0
991 stars 356 forks source link

Missing feature: Hide video buffering time of first playback #1544

Closed cmuellner closed 5 months ago

cmuellner commented 6 months ago

I've used QLC+ in a theater show where two videos were played during the show. The host machine had more than enough capabilities (a recent x86-64 CPU, 16 GB RAM, SATA-SSD with 550 MB/s).

The issue is that it takes quite some time (several seconds for a short video; longer videos take even more time) for the video to start the first playback. Starting any further playback works instantaneously. Several seconds of waiting creates an additional unwanted drama moment that's not acceptable.

The workaround is apparent: play the videos before the show begins. However, the situation is still a bit fragile: even with clear guidelines, the operator might forget to do so.

So, I looked into the code and noticed that QML MediaPlayer is used for video playback. Diving deeper shows that I'm not the first who runs into this issue. A StackOverflow reply suggests the following code to pre-load the video:

QString fileName=QFileDialog::getOpenFileName(this,"Select:","","( *.mp4)");
QFile mediafile(fileName);
mediafile.open(QIODevice::ReadOnly);
QByteArray *ba = new QByteArray();
ba->append(mediafile.readAll());
QBuffer *buffer = new QBuffer(ba);
buffer->open(QIODevice::ReadOnly);
buffer->reset(); //seek 0
player->setMedia(QMediaContent(), buffer);

My assumption is, that mediafile.readAll() above will be the expensive call. Also, note that setMedia has been renamed to setSource in QT6.

The question now is, when is the right time to spend the seconds for loading the video? If we do this on program startup, this becomes annoying. If we do this when starting operator mode, this becomes annoying too. IMHO this should be done as a background activity when opening a workspace (for all included videos) and whenever the video file is updated in the video editor screen. However, loading in background creates new issues: pre-loading needs to be aborted (e.g. when closing the workspace, when changing the video file in the editor screen, and when removing the video from the show).

One of the observations was also that starting the video and immediately stopping it again was enough to trigger the buffering in the background. The QML MediaPlayer does not document this behavior, but it might be a simple solution to the issue: just play the muted video in a window of size 0x0 so that it is loaded.

Maybe more experienced QT developers have better ideas for implement a fix. I still hope I just missed the part where a mmap'ed (and probably mlock'ed) file can be used as media source without the need for useless copies in RAM.

mcallegari commented 6 months ago

Hi, is this related to a specific video codec or a widespread issue? Also, is this related to a specific OS or again same on every supported platform? Qt6 multimedia default backend is FFMPEG (same as VLC) and I wonder if that solves most of the QLC+ related A/V playback issues seen in the forums.

cmuellner commented 5 months ago

Hi, is this related to a specific video codec or a widespread issue?

I don't have much data. The videos both use Quicktime containers and H.264 codecs.

Video 1:

Video 2:

Also, is this related to a specific OS or again same on every supported platform?

OS is Fedora 39. VLC plays both videos instantly.

Qt6 multimedia default backend is FFMPEG (same as VLC) and I wonder if that solves most of the QLC+ related A/V playback issues seen in the forums.

ldd tells me that qlcplus links against libQt5Core.so.5, libQt5Multimedia.so.5, etc. So QT5 is used. Does qlcplus support QT6?

mcallegari commented 5 months ago

Does qlcplus support QT6?

Yes. That's why it's worth to compare the multimedia playback

mcallegari commented 5 months ago

If you have a look at this conversation, it seems Qt 6.x could be a solution: https://www.qlcplus.org/forum/viewtopic.php?t=17214

I need to investigate why audio is not played but it seems there is no delay in video startup

cmuellner commented 5 months ago

I finally found time to test QT6 on Fedora and can confirm that all video playback buffering issues are resolved.

I've confirmed that QT6 is in use with ldd:

[...]
    libQt6MultimediaWidgets.so.6 => /lib64/libQt6MultimediaWidgets.so.6 (0x00007f5f97e85000)
    libQt6Widgets.so.6 => /lib64/libQt6Widgets.so.6 (0x00007f5f96400000)
    libQt6Qml.so.6 => /lib64/libQt6Qml.so.6 (0x00007f5f95e00000)
    libQt6Multimedia.so.6 => /lib64/libQt6Multimedia.so.6 (0x00007f5f95d08000)
    libQt6Gui.so.6 => /lib64/libQt6Gui.so.6 (0x00007f5f95200000)
[...]
    libQt6Network.so.6 => /lib64/libQt6Network.so.6 (0x00007f5f95035000)
    libQt6Core.so.6 => /lib64/libQt6Core.so.6 (0x00007f5f94800000)
[...]

Thanks for the hint!

Unfortunately, with QT6, the audio playback is broken as you mentioned. At least audio from video works.