Question about random() expression
Hi, I'm using this command line to print four consecutive random numbers: ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y out.png The output is always the same four numbers: 0.000000 0.000091 0.285346 0.929202 Why is the first number always zero, even if I write different seed values (here: 0.123) into variable 0? The console output is below. Michael C:\Users\astro\Desktop\LUT1D>ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y out.png ffmpeg version 2023-12-23-git-f5f414d9c4-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers built with gcc 12.2.0 (Rev10, Built by MSYS2 project) configuration: --enable-gpl --enable-version3 --enable-static --pkg-config=pkgconf --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-dxva2 --enable-d3d11va --enable-libvpl --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband libavutil 58. 36.100 / 58. 36.100 libavcodec 60. 36.100 / 60. 36.100 libavformat 60. 20.100 / 60. 20.100 libavdevice 60. 4.100 / 60. 4.100 libavfilter 9. 14.101 / 9. 14.101 libswscale 7. 6.100 / 7. 6.100 libswresample 4. 13.100 / 4. 13.100 libpostproc 57. 4.100 / 57. 4.100 Input #0, lavfi, from 'color=gray:size=1x1,format=gray': Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Video: wrapped_avframe, gray, 1x1 [SAR 1:1 DAR 1:1], 25 fps, 25 tbr, 25 tbn Stream mapping: Stream #0:0 -> #0:0 (wrapped_avframe (native) -> png (native)) Press [q] to stop, [?] for help 0.000000 0.000091 0.285346 0.929202 Output #0, image2, to 'out.png': Metadata: encoder : Lavf60.20.100 Stream #0:0: Video: png, gray(progressive), 1x1 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 25 fps, 25 tbn Metadata: encoder : Lavc60.36.100 png [image2 @ 000001eec3e15700] The specified filename 'out.png' does not contain an image sequence pattern or a pattern is invalid. [image2 @ 000001eec3e15700] Use a pattern such as %03d for an image sequence or use the -update option (with -frames:v 1 if needed) to write a single image. [out#0/image2 @ 000001eec3e15600] video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed= 1.8x
On Wed, Dec 27, 2023 at 4:51 PM Michael Koch <astroelectronic@t-online.de> wrote:
Hi,
I'm using this command line to print four consecutive random numbers:
ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y out.png
The output is always the same four numbers: 0.000000 0.000091 0.285346 0.929202
Why is the first number always zero, even if I write different seed values (here: 0.123) into variable 0?
From: https://ffmpeg.org/ffmpeg-utils.html "Return a pseudo random value between 0.0 and 1.0. x is the index of the internal variable which will be used to save the seed/state." If you're looking for a value between 1 and N, you can probably just multiply it by N (i.e. N=1000, 0.285 * 1000 = 285). Devin -- Devin Heitmueller, Senior Software Engineer LTN Global Communications o: +1 (301) 363-1001 w: https://ltnglobal.com e: devin.heitmueller@ltnglobal.com
Am 27.12.2023 um 23:04 schrieb Devin Heitmueller:
On Wed, Dec 27, 2023 at 4:51 PM Michael Koch <astroelectronic@t-online.de> wrote:
Hi,
I'm using this command line to print four consecutive random numbers:
ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y out.png
The output is always the same four numbers: 0.000000 0.000091 0.285346 0.929202
Why is the first number always zero, even if I write different seed values (here: 0.123) into variable 0? From: https://ffmpeg.org/ffmpeg-utils.html
"Return a pseudo random value between 0.0 and 1.0. x is the index of the internal variable which will be used to save the seed/state."
If you're looking for a value between 1 and N, you can probably just multiply it by N (i.e. N=1000, 0.285 * 1000 = 285).
In my example I'm using the index x=0 and I did set the seed value to 0.123. It's clear that the random function returns values between 0 and 1. My question is why the seed value is ignored. Michael
Michael: On 2023-12-27 13:51, Michael Koch wrote:
...I'm using this command line to print four consecutive random numbers: ... I do not have an answer to your question about the behaviour of the random() function. However, I cannot reproduce your results on my machine. I get an error complaining about the video filter syntax instead. C:\Users\astro\Desktop\LUT1D>ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y out.png ffmpeg version 2023-12-23-git-f5f414d9c4-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers built with gcc 12.2.0 (Rev10, Built by MSYS2 project) configuration: --enable-gpl --enable-version3 --enable-static --pkg-config=pkgconf --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-dxva2 --enable-d3d11va --enable-libvpl --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband libavutil 58. 36.100 / 58. 36.100 libavcodec 60. 36.100 / 60. 36.100 libavformat 60. 20.100 / 60. 20.100 libavdevice 60. 4.100 / 60. 4.100 libavfilter 9. 14.101 / 9. 14.101 libswscale 7. 6.100 / 7. 6.100 libswresample 4. 13.100 / 4. 13.100 libpostproc 57. 4.100 / 57. 4.100 Input #0, lavfi, from 'color=gray:size=1x1,format=gray': Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Video: wrapped_avframe, gray, 1x1 [SAR 1:1 DAR 1:1], 25 fps, 25 tbr, 25 tbn Stream mapping: Stream #0:0 -> #0:0 (wrapped_avframe (native) -> png (native)) Press [q] to stop, [?] for help 0.000000 0.000091 0.285346 0.929202 Output #0, image2, to 'out.png': Metadata: encoder : Lavf60.20.100 Stream #0:0: Video: png, gray(progressive), 1x1 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 25 fps, 25 tbn Metadata: encoder : Lavc60.36.100 png [image2 @ 000001eec3e15700] The specified filename 'out.png' does not contain an image sequence pattern or a pattern is invalid. [image2 @ 000001eec3e15700] Use a pattern such as %03d for an image sequence or use the -update option (with -frames:v 1 if needed) to write a single image. [out#0/image2 @ 000001eec3e15600] video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed= 1.8x
===== % ffmpeg -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0));0' -frames 1 -y ~/tmp/ignore.png ffmpeg version 4.4.4 Copyright (c) 2000-2023 the FFmpeg developers built with Apple clang version 14.0.0 (clang-1400.0.29.202) configuration: --prefix=/opt/local --cc=/usr/bin/clang --mandir=/opt/local/share/man --enable-audiotoolbox --disable-indev=jack --disable-libjack --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-opencl --disable-outdev=xv --enable-sdl2 --disable-securetransport --enable-videotoolbox --enable-avfilter --enable-avresample --enable-fontconfig --enable-gnutls --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libfribidi --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libzimg --enable-libzvbi --enable-lzma --enable-pthreads --enable-shared --enable-swscale --enable-zlib --enable-libaom --enable-libsvtav1 --arch=arm64 --enable-gpl --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-postproc libavutil 56. 70.100 / 56. 70.100 libavcodec 58.134.100 / 58.134.100 libavformat 58. 76.100 / 58. 76.100 libavdevice 58. 13.100 / 58. 13.100 libavfilter 7.110.100 / 7.110.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100 Input #0, lavfi, from 'color=gray:size=1x1,format=gray': Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Video: rawvideo (Y800 / 0x30303859), gray, 1x1 [SAR 1:1 DAR 1:1], 25 tbr, 25 tbn, 25 tbc Stream mapping: Stream #0:0 -> #0:0 (rawvideo (native) -> png (native)) Press [q] to stop, [?] for help [Parsed_geq_0 @ 0x123705630] [Eval @ 0x16eefcef8] Missing ')' or too many args in 'st(0' [AVFilterGraph @ 0x124807b20] Error initializing filter 'geq' with args 'lum=st(0' Error reinitializing filters! Failed to inject frame into filter network: Invalid argument Error while processing the decoded data for stream #0:0 Conversion failed! ===== This is with FFMpeg 4.4.4 via MacPorts on macOS 12.7.2 Monterey. Could you perhaps make a simpler command line invocation, which just runs random() and does not generate a grey image or write a file? Hope this clears a way to helpful answers, —Jim DeLaHunt
Am 27.12.2023 um 23:59 schrieb Jim DeLaHunt:
Michael:
On 2023-12-27 13:51, Michael Koch wrote:
...I'm using this command line to print four consecutive random numbers: ... I do not have an answer to your question about the behaviour of the random() function. However, I cannot reproduce your results on my machine. I get an error complaining about the video filter syntax instead.
If not on a Windows machine, you may have to encapsulate the filter thread in double quotes. Please try this command: ffmpeg -filter_threads 1 -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf "geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0))'" -frames 1 -y out.png
Could you perhaps make a simpler command line invocation, which just runs random() and does not generate a grey image or write a file?
I don't know how I could simplify it. random() is an expression. To use it, I need a filter that accepts an expression. For the filter I need an image to work on. Even if it has only one pixel, as in my example. Michael
Michael: On 2023-12-27 15:20, Michael Koch wrote:
Am 27.12.2023 um 23:59 schrieb Jim DeLaHunt:
Michael:
On 2023-12-27 13:51, Michael Koch wrote:
...I'm using this command line to print four consecutive random numbers: ... I do not have an answer to your question about the behaviour of the random() function. However, I cannot reproduce your results on my machine. I get an error complaining about the video filter syntax instead.
If not on a Windows machine, you may have to encapsulate the filter thread in double quotes. Please try this command: ffmpeg -filter_threads 1 -loglevel repeat -f lavfi -i color=gray:size=1x1,format=gray -vf "geq=lum='st(0,0.123);print(random(0));print(random(0));print(random(0));print(random(0))'" -frames 1 -y out.png
Right you are. Enclosing the filter expression in double quotes, I was able to reproduce your result. Four numbers printed out, and the first of them was 0.000000. The remaining three were exactly the same as your output. That makes those numbers seem not very random. Interestingly, when I change "random(0)" to "random(0.9)", I get the identical sequence of four numbers. The behaviour of the parameter is not the "seed" behaviour that I expect. The documentation says, "x is the index of the internal variable which will be used to save the seed/state." (https://ffmpeg.org/ffmpeg-all.html#Expression-Evaluation). I don't know what it means by "index of the internal variable", and I don't know what "save" means. In a function named random(), I expect the parameter to be used as a seed. I guess this is one of the places where one has to read the source code. Apologies for my confusion, —Jim DeLaHunt
On 12/27/2023 3:54 PM, Jim DeLaHunt wrote:
The documentation says, "x is the index of the internal variable which will be used to save the seed/state." (https://ffmpeg.org/ffmpeg-all.html#Expression-Evaluation). I don't know what it means by "index of the internal variable", and I don't know what "save" means. In a function named random(), I expect the parameter to be used as a seed. I guess this is one of the places where one has to read the source code.
I also suspect that "read the source" is the answer, but also recall from decades past that some systems (e.g. BASIC) needed a "randomize" statement in order to get off their usual starting point. Off to the source :). z!
Am 28.12.2023 um 03:25 schrieb Carl Zwanzig:
On 12/27/2023 3:54 PM, Jim DeLaHunt wrote:
The documentation says, "x is the index of the internal variable which will be used to save the seed/state." (https://ffmpeg.org/ffmpeg-all.html#Expression-Evaluation). I don't know what it means by "index of the internal variable", and I don't know what "save" means. In a function named random(), I expect the parameter to be used as a seed. I guess this is one of the places where one has to read the source code.
I also suspect that "read the source" is the answer, but also recall from decades past that some systems (e.g. BASIC) needed a "randomize" statement in order to get off their usual starting point.
I figured out what's going on. It seems the memory of variable 0 is a union of int and double. When used by the expressions ld() and st(), it's double. When used by random(), then it's int. Important thing to remember: If you want to set the random generator to a seed value much different from 0, then you have to use rather big numbers, for example 2^41. Michael
participants (4)
-
Carl Zwanzig -
Devin Heitmueller -
Jim DeLaHunt -
Michael Koch