Based on Gyan's answer, here are more details.
The following creates a video from an image and an mp3 with an infinite zoom-in-out on the image:
ffmpeg -loop 1 -i img.png -i adio.mp3 -vf "[0:v]scale=7680x4320,zoompan=z='if(gte(zoom,1.5)+eq(ld(1),1)*gt(zoom,1),zoom-0.00005*st(1,1),zoom+0.00005+st(1,0))':d=20000" -c:a copy -c:v libx264 -shortest out3.mp4
[0:v]scale=7680x4320
upscales 4 times the original 1920x1080 image for a smooth transition.
d=20000
specifies the duration of the zoom-in-out. In this case, I perform a zoom from 1 to 1.5 with increments or decrements of 0.00005. That's (1.5-1) / 0.00005 steps for the zoom, which means I need two times this for the zoom + dezoom, which is 10'000*2 = 20'000.
if(gte(zoom,1.5)+eq(ld(1),1)*gt(zoom,1),zoom-0.00005*st(1,1),zoom+0.00005+st(1,0))
can be translated to the following pseudo-code:
// '||' corresponds to a `+` and '&&' to a '*'
if zoom >= 1.5 || (isDezooming && zoom > 1) {
zoom-0.00005
isDezooming = true // corresponds to '*st(1,1)'
} else {
zoom+0.00005
isDezooming = false // corresponds to '+st(1,0)'
}
where isDezooming
corresponds to the variable 1
handled with the ld(1)
and st(1,0)
instructions. Here is the full list of instruction.