[FFmpeg-trac] #6127(avfilter:new): non-intuitive behavior of random() function used in zoompan filter's expressions

FFmpeg trac at avcodec.org
Sun Feb 5 01:07:11 EET 2017


#6127: non-intuitive behavior of random() function used in zoompan filter's
expressions
----------------------------------+--------------------------------------
             Reporter:  pbasista  |                     Type:  defect
               Status:  new       |                 Priority:  normal
            Component:  avfilter  |                  Version:  git-master
             Keywords:  zoompan   |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+--------------------------------------
 Summary of the bug:

 when random() function is used in a naive way (i.e. "`random(0)`", without
 previously setting the internal variable `0`) inside an expression for
 zoompan filter's options, it always returns the *same* number which is
 very close to zero:

 {{{
 $ /usr/bin/ffmpeg -loop 1 -i alley.png -filter
 "zoompan='s=1920x1200:fps=60:z=3:y=y+print(random(0)*1000000000):x=x+print(random(1)*1000000000)'"
 -frames 600 output.hevc -y
 ffmpeg version 3.2.2-2 Copyright (c) 2000-2016 the FFmpeg developers
   built with gcc 6.3.0 (Debian 6.3.0-4) 20170121
   configuration: --prefix=/usr --extra-version=2 --toolchain=hardened
 --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu
 --enable-gpl --disable-stripping --enable-avresample --enable-avisynth
 --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray
 --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128
 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-
 libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-
 libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse
 --enable-librubberband --enable-libshine --enable-libsnappy --enable-
 libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-
 libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack
 --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq
 --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-
 sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint
 --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
   libavutil      55. 34.100 / 55. 34.100
   libavcodec     57. 64.101 / 57. 64.101
   libavformat    57. 56.100 / 57. 56.100
   libavdevice    57.  1.100 / 57.  1.100
   libavfilter     6. 65.100 /  6. 65.100
   libavresample   3.  1.  0 /  3.  1.  0
   libswscale      4.  2.100 /  4.  2.100
   libswresample   2.  3.100 /  2.  3.100
   libpostproc    54.  1.100 / 54.  1.100
 [png_pipe @ 0x557e77849f00] Stream #0: not enough frames to estimate rate;
 consider increasing probesize
 Input #0, png_pipe, from 'alley.png':
   Duration: N/A, bitrate: N/A
     Stream #0:0: Video: png, rgb24(pc), 7360x4912, 25 tbr, 25 tbn, 25 tbc
 x265 [info]: HEVC encoder version 0.0
 x265 [info]: build info [Linux][GCC 6.2.0][64 bit] 8bit+10bit+12bit
 x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX AVX2
 FMA3 LZCNT BMI2
 x265 [info]: Main 4:4:4 profile, Level-5 (Main tier)
 x265 [info]: Thread pool created using 8 threads
 x265 [info]: Slices                              : 1
 x265 [info]: frame threads / pool features       : 3 / wpp(19 rows)
 x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
 x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
 x265 [info]: ME / range / subpel / merge         : hex / 57 / 2 / 2
 x265 [info]: Keyframe min / max / scenecut       : 25 / 250 / 40
 x265 [info]: Cb/Cr QP Offset                     : 6 / 6
 x265 [info]: Lookahead / bframes / badapt        : 20 / 4 / 2
 x265 [info]: b-pyramid / weightp / weightb       : 1 / 1 / 0
 x265 [info]: References / ref-limit  cu / depth  : 3 / on / on
 x265 [info]: AQ: mode / str / qg-size / cu-tree  : 1 / 1.0 / 32 / 1
 x265 [info]: Rate Control / qCompress            : CRF-28.0 / 0.60
 x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-
 smoothing
 x265 [info]: tools: lslices=7 deblock sao
 Output #0, hevc, to 'output.hevc':
   Metadata:
     encoder         : Lavf57.56.100
     Stream #0:0: Video: hevc (libx265), gbrp, 1920x1200, q=2-31, 60 fps,
 60 tbn, 60 tbc
     Metadata:
       encoder         : Lavc57.64.101 libx265
 Stream mapping:
   Stream #0:0 -> #0:0 (png (native) -> hevc (libx265))
 Press [q] to stop, [?] for help
 0.054964
     Last message repeated 1 times
 0.054964  1 fps=0.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A
 speed=   0x
     Last message repeated 19 times
 0.054964 11 fps=8.5 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A
 speed=   0x
     Last message repeated 15 times
 [swscaler @ 0x557e79781500] Warning: data is not aligned! This can lead to
 a speedloss
 0.054964
     Last message repeated 5 times
 0.054964 22 fps= 12 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A
 speed=   0x
     Last message repeated 15 times
 0.054964 30 fps= 13 q=-0.0 size=       6kB time=-00:00:00.01 bitrate=N/A
 speed=N/A
     Last message repeated 15 times
 0.054964 38 fps= 13 q=-0.0 size=       7kB time=00:00:00.11 bitrate=
 501.0kbits/s speed=0.04x
     Last message repeated 17 times
 0.054964 47 fps= 14 q=-0.0 size=       9kB time=00:00:00.26 bitrate=
 261.3kbits/s speed=0.077x
     Last message repeated 17 times
 0.054964 56 fps= 14 q=-0.0 size=      10kB time=00:00:00.41 bitrate=
 190.8kbits/s speed=0.104x
     Last message repeated 17 times
 0.054964 65 fps= 14 q=-0.0 size=      11kB time=00:00:00.56 bitrate=
 152.7kbits/s speed=0.125x
     Last message repeated 15 times
 0.054964 73 fps= 14 q=-0.0 size=      12kB time=00:00:00.70 bitrate=
 141.1kbits/s speed=0.139x
     Last message repeated 17 times
 0.054964 82 fps= 15 q=-0.0 size=      13kB time=00:00:00.85 bitrate=
 127.0kbits/s speed=0.152x
     Last message repeated 15 times

 ...
 }}}

 The output above is from Debian's version of ffmpeg, but the same behavior
 can be experienced in git-master version as of today.

 '''Explanation:'''

 zoompan filter uses the internal formula evaluator to *parse* and evaluate
 the expressions for its options. The parsing is done for *every* frame
 (see function `output_single_frame` in `libavfilter/vf_zoompan.c`, line
 135). This means that for every frame, the evaluator initializes the
 parser's internal variables 0-9 for each of the parsed expressions to zero
 (see function `av_expr_parse` in `libavutil/eval.c`, line 667). Therefore,
 no function is able to store its internal state into one of the internal
 variables and use it during the next evaluation (which is typically for
 the next frame), because there will always be only a ''single'' evaluation
 for every parsed expression.

 This breaks the intuitive behavior of functions which require internal
 state, like random(). It uses an internal variable to store its current
 "seed" from which it calculates the next pseudorandom number (see function
 `eval_expr` in `libavutil/eval.c`, line 220). When the seed value is
 always the same (i.e. zero), the generated "pseudorandom" number is always
 the same as well.

 '''Suggestion:'''

 This non-intuitive behavior is caused by the fact that the expressions are
 parsed for every frame. If the expressions were parsed only during the
 filter's initialization and evaluated for every frame, the internal
 variables would be preserved and the above described problem would not
 exist. Some other filters, like the crop filter, use this technique and I
 believe it would be better if zoompan used it as well.

--
Ticket URL: <https://trac.ffmpeg.org/ticket/6127>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list