What's a good efficient way to reverse a QMovie to play it backwards?
-
Hi,
What is your use case ?
-
The other option would be to have the file containing directly both directions.
-
Well, in the absolute, it could work.
One thing you can do is check the implementation of QMovie and see if you can mimic it for backward playback. -
Well, in the absolute, it could work.
One thing you can do is check the implementation of QMovie and see if you can mimic it for backward playback.@SGaist Here's the actual use case, It's a bit laggy though. The unselected A B C D bank indicators jump to frame 0 when a new bank is selected, I want to try to reverse the animation of the previous bank instead of jumping to 0.
I'll try some things tomorrow
-
@SGaist Here's the actual use case, It's a bit laggy though. The unselected A B C D bank indicators jump to frame 0 when a new bank is selected, I want to try to reverse the animation of the previous bank instead of jumping to 0.
I'll try some things tomorrow
@Mizmas Have you tried setting the cache mode to CacheAll prior to running the animation forward?
https://doc.qt.io/qt-6/qmovie.html#cacheMode-prop:
Caching frames can be useful when the underlying animation format handler that QMovie relies on to decode the animation data does not support jumping to particular frames in the animation, or even "rewinding" the animation to the beginning (for looping)
-
@Mizmas Have you tried setting the cache mode to CacheAll prior to running the animation forward?
https://doc.qt.io/qt-6/qmovie.html#cacheMode-prop:
Caching frames can be useful when the underlying animation format handler that QMovie relies on to decode the animation data does not support jumping to particular frames in the animation, or even "rewinding" the animation to the beginning (for looping)
@jeremy_k Do you mean for the laggy animation? I've tried it, but I didn't get a noticeable performance improvement. I'm using a .webp animation file though to have a full transparency channel, if I use .gif the lag is minimal, but it doesn't have full transparency, only 0 or 1
-
Unfortunately you can't set a negative speed but reading the QMovie code, calling jumpToFrame via a QTimer externally isn't that much different than what start() is doing internally.
-
Unfortunately you can't set a negative speed but reading the QMovie code, calling jumpToFrame via a QTimer externally isn't that much different than what start() is doing internally.
@GrecKo
Purely ooi for me. What kind ofQTimer
do you use? From my limited understanding of this stuff you need the human to see at least 50 frames per second, right? IsQTimer
"accurate" and "consistent" enough to make this smooth, or does it get "lumpy" as the timeouts vary in accuracy? -
The way it is done is to start the QTimer after each frame, with the timeout being the frame minus the time it took to process the current frame.
-
@GrecKo
Purely ooi for me. What kind ofQTimer
do you use? From my limited understanding of this stuff you need the human to see at least 50 frames per second, right? IsQTimer
"accurate" and "consistent" enough to make this smooth, or does it get "lumpy" as the timeouts vary in accuracy?@JonB said in What's a good efficient way to reverse a QMovie to play it backwards?:
human to see at least 50 frames per second
Smartass mode: 24 actually :-)
-
OK, so does a default precision
QTimer
tick accurately at at least 24 per second? Not to mention that presumably if the OS is off doing something it won't, but perhaps all movie players would suffer from that issue?@JonB Such low frequencies should be fine for QTimer I would say.
https://doc.qt.io/qt-6/qt.html#TimerType-enum
"On UNIX (including Linux, macOS, and iOS), Qt will keep millisecond accuracy for Qt::PreciseTimer.
...
On Windows, Qt will use Windows's Multimedia timer facility (if available) for Qt::PreciseTimer" -
@JonB Such low frequencies should be fine for QTimer I would say.
https://doc.qt.io/qt-6/qt.html#TimerType-enum
"On UNIX (including Linux, macOS, and iOS), Qt will keep millisecond accuracy for Qt::PreciseTimer.
...
On Windows, Qt will use Windows's Multimedia timer facility (if available) for Qt::PreciseTimer" -
QMovie uses a default QTimer.
-
@jeremy_k Do you mean for the laggy animation? I've tried it, but I didn't get a noticeable performance improvement. I'm using a .webp animation file though to have a full transparency channel, if I use .gif the lag is minimal, but it doesn't have full transparency, only 0 or 1
@Mizmas said in What's a good efficient way to reverse a QMovie to play it backwards?:
@jeremy_k Do you mean for the laggy animation? I've tried it, but I didn't get a noticeable performance improvement.
Yes, to decrease the time required to access each frame when playing in reverse. Have you profiled the code to verify that the animation is a hotspot?
I'm using a .webp animation file though to have a full transparency channel, if I use .gif the lag is minimal, but it doesn't have full transparency, only 0 or 1
Webp uses VP8, which stores key frames and intermediate frames that modify earlier frames. Jumping to a frame may require reconstructing prior frames first.
-
@Mizmas said in What's a good efficient way to reverse a QMovie to play it backwards?:
@jeremy_k Do you mean for the laggy animation? I've tried it, but I didn't get a noticeable performance improvement.
Yes, to decrease the time required to access each frame when playing in reverse. Have you profiled the code to verify that the animation is a hotspot?
I'm using a .webp animation file though to have a full transparency channel, if I use .gif the lag is minimal, but it doesn't have full transparency, only 0 or 1
Webp uses VP8, which stores key frames and intermediate frames that modify earlier frames. Jumping to a frame may require reconstructing prior frames first.
@jeremy_k Thanks for the help. What I did was create a minimal new .py file with only a QLabel and a QMovie to only test the animation, and the performance is exactly the same as in the video I shared before, so it seems that there was nothing bottlenecking the animation in my main app code. I'm on PyQt6 6.7.1 if that helps.
On the left it's opened on Chrome, and on the right PyQt6 window:
from PyQt6.QtWidgets import QApplication, QLabel from PyQt6.QtGui import QMovie import sys import resources app = QApplication(sys.argv) label = QLabel() label.setStyleSheet("background: black;") movie = QMovie(':/Animations/b_mode.webp') movie.setCacheMode(QMovie.CacheMode.CacheAll) print(movie.cacheMode()) print(movie.format()) label.setMovie(movie) label.setFixedSize(50, 50) label.show() movie.start() sys.exit(app.exec())
-
@Mizmas Thanks for providing the POC. I gave it a quick try with a test image, but apparently my Qt installation lacks webp movie support.
The image on the right appears to be less smooth than the one on the left. Does it look any better if the label is allowed to assume its implicit size from the QMovie rather than being set to 50x50?