-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gdkpixbuf: Add support for loading image sequences #1325
base: main
Are you sure you want to change the base?
Conversation
fa982d6
to
6c085ff
Compare
Hiers: Thank you for your contribution. We don't maintain the gdk-pixbuf code (which is why it's in the contrib/ directory). I will ask the author to review your pull request. @novomesk Daniel: Could you take a look at this? Thanks. |
This is good feature enhancement. I was thinking to focus adding animation anyway. However, I will need more time to understand, check and test the code. Maybe I will add some tweaks afterwards. @wantehchang Is the new release planned soon? I don't like to add big changes close to the release. |
Daniel: We don't have a plan to make a new libavif release soon, say in the next two weeks. |
I have an example here of a file that will eventually fail. It has no problems when ran through ffplay. It's the only file I've created from a video (webm) and the only avif image sequence that I've seen fail. It could be hitting an edge case that I'm not handling in my patch. |
What does it mean that the |
When I open that animation, after looping a few times it will either disappear for a moment with |
What application/version you are using to play animation, so I can try to reproduce the crashes? |
xviewer version 3.2.12 |
I am able to reproduce the problem with EOG application and with different AVIF animation too.
|
In |
Is there anything in common with the files that cause this problem?
Yeah, good catch. Unfortunately, the old bug still persists after I make these changes. |
In
In It would be fine to add error checking after each frame if
I see the approach used here is to load all frames into memory and then to return cached pixels. I used similar approach in my Qt plug-ins in the past. Problem was that large+long animations too noticeable long time at the beginning to decode and memory consumption grows quickly. |
You got me on the right path to fix that bug. The comment I left on whether the precision loss of me converting that double to an unsigned int was somewhat prescient, as that was what was causing problems. I've changed how the total time of the animation in milliseconds is used and it seems to have fixed it. I was hoping the way I was loading everything at once wouldn't be a problem because I've never seen an avif/gif/etc animation that was more than a few seconds long, but I'll try a more sensible approach. |
9566ccd
to
2c2841a
Compare
I am sending you a large animation: |
My current issue with having a reasonable limit or decoding frames as they are needed is that any decoding done after the animation starts playing will affect it. Whether it has small constant stutters when decoding one frame, or fewer bigger stutters when decoding a larger set of frames. I can only think of offloading the decoding work to a separate thread, but I didn't want to go that route if there is a better solution. |
I like the idea with decoder thread and cache of few future frames. Of course, it is most difficult to implement and test. |
I implemented the decoder thread. I have two issues, one of which is not knowing if using the |
Also, what do you think of the buffer size? It looks very small when used for low res animations, but will quickly grow if used with high quality 1080p animations. Instead of the buffer being X frames, it might be better to make it be X MB instead. But maybe it's not a big deal. |
Buffer with 64 frames means more than 1 second of 60fps video. I think it is enough. Animations with small dimensions decode quickly and typically it can play smoothly also without buffering. Note: I observed that |
Ok, if you're happy with the PR, I'm happy with it as it is. |
When I exit
Here is a testfile http://188.121.162.14/avif/repetition3.avif with Repeat Count 3 (plays 4 times totally in browsers). repetition3.avif plays infinitely in eog. Is it possible to make it to play only 4 times in eog? |
I've fixed it, but EOG and EOG forks have a bug with files that have a repeat count > 0. Since once it stops repeating the pixbuf will never need to be updated and EOG is not expecting this, it will be stuck in a while loop and the GUI will stop responding. But this is not something on the pixbuf module's end. |
Hmm, Perhaps we can find inspiration in their sources? https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/tree/master/gdk-pixbuf |
I've rummaged in the code a bit, and the reason EOG and its forks work with gif is because they never even run the code that will loop incessantly. For some reason, a gif (or at least the gif you gave here as an example) has the delay time for the last frame of the last loop as a very very big number. It might hit the bug I've mentioned once that ridiculous timer runs out, but I didn't care to wait. |
In short, EOG does have a bug with animations that have a set number of loops, but gifs work in a way that hide that bug. |
Are you willing to explain the problem to the EOG developers? In case they don't fix I suggest we always loop the animation infinitely. |
I did not forget about this PR. Lot of work was done and valuable experiences were gathered. We have valuable prototype. But I would not merge yet. I intend to inspect the code more deeply when I have more time. |
The big problem we had with a bug in EOG and EOG forks that led to an animation using 100% of a cpu core when the animation finished has been fixed. That was the last thing I was waiting on. As for me, this can get merged. |
…ing functions to fit in with GdkPixbufAnimation.
…g, as according to the GDK documentation.
025423d
to
6f68d6e
Compare
@novomesk I refactored a function that was a bit too big to be easily understandable and also changed the get_delay function to always return a value following the documentation. If you've got time, check if this is ready to be merged. |
clang compiler doesn't like it:
And in |
Thanks, I never thought of catching errors by running clang on it. |
I am getting crashes in eog after playing AVIF animation for few seconds. The first crash:
The second crash:
|
The first crash should be fixed, but I'm surprised a NULL pointer de-reference didn't cause a segfault unless it was ran in gdb... I hope this commit fixes the second crash, because I've no idea what caused it and can't reproduce it. The backtrace doesn't even include anything specific to our .so. |
Now it doesn't crash but playback stops after few seconds. When the animation stops, these messages appear:
|
Well, I changed something, but I don't think it's going to fix this bug. I can't for the life of me replicate it. If this didn't fix it for you, can you run it again and try to get some more debugging information? I'm at a loss at what is going wrong. |
I'll look into it a bit later when I have more time. |
Fixed what I think is the most likely culprit of the messages you were getting. It's related to a race condition between the thread displaying the image and the thread decoding the avif file; There's a potential situation where the first thread will go beyond what is in the buffer if the decoder lags behind. Getting this merged will be a pain though, with #1907 touching so many lines. |
A working patch implementing image sequences in the gdkpixbuf module.
I'm not familiar with GLib/GTK, so be extra careful with merging this as it might have some beginner bugs.