JuliaPlots / Plots.jl

Powerful convenience for Julia visualizations and data analysis
https://docs.juliaplots.org
Other
1.84k stars 355 forks source link

Quality of gifs generated by ffmpeg can be improved by using a palette #1050

Closed H-M-H closed 7 years ago

H-M-H commented 7 years ago

Currently FFmpeg produces really low quality animations as the colors are nearly always off. This is unfortunate especially as ImageMagicks convert does not cope that good with longer animations whereas FFmpeg does. Using a palette resolves this issue and the resulting gifs are pretty much of the same quality.

Docs for creating and using a palette can be found here: https://ffmpeg.org/ffmpeg-filters.html#palettegen-1 https://ffmpeg.org/ffmpeg-filters.html#paletteuse

mkborregaard commented 7 years ago

Thanks for the heads up, that looks nice.

H-M-H commented 7 years ago

Looking at https://github.com/JuliaPlots/Plots.jl/blob/b0ffe03c999a45d87db3e74215fa725615357098/src/animation.jl#L93 it is probably sufficient to change the ffmpeg call to these two calls:

run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.png`)
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.png -lavfi paletteuse -y $fn`)
mkborregaard commented 7 years ago

Do you feel in the mood for a PR? :-)

juliohm commented 7 years ago

I am not sure this can affect performance, but it would be interesting to check if the new approach slows things down. I sometimes need to generate some expensive long gifs and a small difference per frame can cause a big difference in the total.

H-M-H commented 7 years ago

I did some research based on the pngs generated by the Lorenz Attractor example but creating a png for every step (so we end up with 1500 files). The results are as follows:

convert - 2min 05.47s - 43MiB

> time convert -delay 5 -loop 0 {000001..001500}.png -alpha off convert.gif
convert -delay 5 -loop 0 {000001..001500}.png -alpha off convert.gif  275.95s user 45.61s system 256% cpu 2:05.47 total

Resulted in a 43MiB file, GitHub won't even let me upload it. While generating convert ate up quite a bit RAM and disk space so I had to increase:

<policy domain="resource" name="memory" value="2GiB"/> # previously 256MiB
<policy domain="resource" name="disk" value="3GiB"/> # previously 1GiB

in /etc/ImageMagick-6/policy.xml

Current ffmpeg command - 5.546s - 3.7MiB

time ffmpeg -v 0 -framerate 20 -loop 0 -i %06d.png -y ffmpeg_old.gif
ffmpeg -v 0 -framerate 20 -loop 0 -i %06d.png -y ffmpeg_old.gif  8.61s user 0.04s system 156% cpu 5.546 total

ffmpeg_old

Proposed ffmpeg command - 10.787s - 119KiB

> time (ffmpeg -v 0 -i %06d.png -vf palettegen -y palette.png && ffmpeg -v 0 -framerate 20 -loop 0 -i %06d.png -i palette.png -lavfi paletteuse -yffmpeg.gif)
( ffmpeg -v 0 -i %06d.png -vf palettegen -y palette.png && ffmpeg -v 0  20  0)  16.68s user 0.18s system 156% cpu 10.787 total

ffmpeg


As of this results completely replacing convert by ffmpeg is probably a good idea, also note that generating all the pngs took some considerable amount of time too.

mkborregaard commented 7 years ago

That does sound like ffmpeg is preferable. I am not sure why your colors are so much off though - I've never seen that before.