Opened 5 years ago

Closed 4 years ago

#732 closed enhancement (wontfix)

Storing variables not working in expressions

Reported by: jworrall Owned by:
Priority: normal Component: avutil
Version: unspecified Keywords: expression evaluation scale
Cc: coniophora@gmail.com Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Storing a variable does not allow it to be retrieved:

-vf "scale = st(0\,1) * 640 : ld(0) * 480"

The first function, st(0,1), evaluates to 1, and the output file has a width of 640.
The second function, ld(0), apparently evaluates to 0, and the output retains its original height.

My understanding is that ld(0) should reload var 0 with a value of 1.

Following is a typical complete command line and full output. Problem is not limited to one input file:

ffmpeg -i kit.mov -t 3 -c:v libx264 \
-vf "scale = st(0\,1) * 640 : ld(0) * 480" \
-vprofile main -preset veryslow -x264opts level=3.1:ref=8 -c:a libvo_aacenc -y output.m4v

ffmpeg version 0.8.7.git-337ce55, Copyright (c) 2000-2011 the FFmpeg developers

built on Dec 10 2011 09:35:29 with clang 3.0 (tags/Apple/clang-211.12)
configuration: --prefix=/Volumes/Ramdisk?/sw --cc=clang --enable-gpl --enable-version3 --arch=x86_64 --enable-hardcoded-tables --disable-indevs --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libvo-aacenc --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libx264 --enable-libvorbis --enable-libtheora --enable-libspeex --disable-ffserver
libavutil 51. 32. 0 / 51. 32. 0
libavcodec 53. 42. 0 / 53. 42. 0
libavformat 53. 24. 0 / 53. 24. 0
libavdevice 53. 4. 0 / 53. 4. 0
libavfilter 2. 52. 0 / 2. 52. 0
libswscale 2. 1. 0 / 2. 1. 0
libpostproc 51. 2. 0 / 51. 2. 0

Seems stream 0 codec frame rate differs from container frame rate: 1200.00 (1200/1) -> 29.97 (30000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'kit.mov':

Metadata:

major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2011-05-08 00:51:03

Duration: 00:01:21.61, start: 0.000000, bitrate: 10723 kb/s

Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1280x720, 10655 kb/s, 29.81 fps, 29.97 tbr, 600 tbn, 1200 tbc
Metadata:

creation_time : 2011-05-08 00:51:03
handler_name :

Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, s16, 63 kb/s
Metadata:

creation_time : 2011-05-08 00:51:03
handler_name : ?Apple Alias Data Handler

[buffer @ 0x7fb642c165a0] w:1280 h:720 pixfmt:yuv420p tb:1/1000000 sar:0/1 sws_param:
[scale @ 0x7fb642c1fdc0] w:1280 h:720 fmt:yuv420p -> w:640 h:720 fmt:yuv420p flags:0x4
[libx264 @ 0x7fb643031800] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle? SSE4.2
[libx264 @ 0x7fb643031800] profile Main, level 3.1
[libx264 @ 0x7fb643031800] 264 - core 120 - H.264/MPEG-4 AVC codec - Copyleft 2003-2011 - http://www.videolan.org/x264.html - options: cabac=1 ref=8 deblock=1:0:0 analyse=0x1:0x131 me=umh subme=10 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=24 chroma_me=1 trellis=2 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=8 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=60 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, ipod, to 'output.m4v':

Metadata:

major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2011-05-08 00:51:03
encoder : Lavf53.24.0
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 640x720, q=-1--1, 30k tbn, 29.97 tbc
Metadata:

creation_time : 2011-05-08 00:51:03
handler_name :

Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, s16, 128 kb/s
Metadata:

creation_time : 2011-05-08 00:51:03
handler_name : ?Apple Alias Data Handler

Stream mapping:

Stream #0:0 -> #0:0 (h264 -> libx264)
Stream #0:1 -> #0:1 (aac -> libvo_aacenc)

Press [q] to stop, ? for help
frame= 90 fps= 12 q=-1.0 Lsize= 206kB time=00:00:02.93 bitrate= 574.6kbits/s
video:154kB audio:47kB global headers:0kB muxing overhead 2.113484%
[libx264 @ 0x7fb643031800] frame I:1 Avg QP:24.70 size: 14288
[libx264 @ 0x7fb643031800] frame P:17 Avg QP:25.77 size: 4099
[libx264 @ 0x7fb643031800] frame B:72 Avg QP:30.15 size: 1021
[libx264 @ 0x7fb643031800] consecutive B-frames: 1.1% 0.0% 0.0% 13.3% 44.4% 33.3% 7.8% 0.0% 0.0%
[libx264 @ 0x7fb643031800] mb I I16..4: 51.5% 0.0% 48.5%
[libx264 @ 0x7fb643031800] mb P I16..4: 1.7% 0.0% 1.3% P16..4: 41.2% 7.2% 9.9% 0.1% 0.0% skip:38.6%
[libx264 @ 0x7fb643031800] mb B I16..4: 0.0% 0.0% 0.0% B16..8: 43.1% 1.8% 0.2% direct: 0.3% skip:54.5% L0:43.0% L1:55.7% BI: 1.3%
[libx264 @ 0x7fb643031800] direct mvs spatial:94.4% temporal:5.6%
[libx264 @ 0x7fb643031800] coded y,uvDC,uvAC intra: 43.6% 34.0% 12.2% inter: 1.6% 2.1% 0.0%
[libx264 @ 0x7fb643031800] i16 v,h,dc,p: 50% 5% 6% 39%
[libx264 @ 0x7fb643031800] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 30% 2% 15% 9% 14% 10% 8% 7% 5%
[libx264 @ 0x7fb643031800] i8c dc,h,v,p: 44% 21% 27% 8%
[libx264 @ 0x7fb643031800] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x7fb643031800] ref P L0: 50.3% 14.3% 17.2% 5.4% 4.5% 3.1% 3.4% 1.8%
[libx264 @ 0x7fb643031800] ref B L0: 82.3% 10.1% 4.4% 1.7% 0.8% 0.5% 0.2%
[libx264 @ 0x7fb643031800] ref B L1: 89.7% 10.3%
[libx264 @ 0x7fb643031800] kb/s:419.56
localhost:Desktop jim$

Change History (5)

comment:1 Changed 5 years ago by jworrall

Sorry I used external libraries with that command.
This gives the same incorrect result:

ffmpeg -i kit.mov -t 3 \
-vf "scale = st(0\,1) * 640 : ld(0) * 480" \
-y output.mpg

I don't think it matters what input file or format is used.

comment:2 follow-up: Changed 5 years ago by michael

  • Type changed from defect to enhancement

The variables are currently not preserved between expressions.
Maybe you can explain for what you want this feature?

comment:3 in reply to: ↑ 2 ; follow-up: Changed 5 years ago by jworrall

Oh, well, that explains a lot. It seems the variables would be more powerful if they could be shared between expressions. For example, I am trying to write a scale filter that will scale a video of any size and aspect ratio down (but not up) to fit inside an iPhone display, while preserving aspect ratio. I've written a script that gets variables for the display/frame size depending on which iPhone it is (FW, FH and the aspect ratio FA).

I was eventually able to do it without variables; it looks like this:
-vf "scale = min(1\,gt(iw\,$FW)+gt(ih\,$FH)) * (gte(a\,$FA)*$FW + lt(a\,$FA)*(($FH*iw)/ih)) + not(min(1\,gt(iw\,$FW)+gt(ih\,$FH)))*iw : \
min(1\,gt(iw\,$FW)+gt(ih\,$FH)) * (lte(a\,$FA)*$FH + gt(a\,$FA)*(($FW*ih)/iw)) + not(min(1\,gt(iw\,$FW)+gt(ih\,$FH)))*ih" \

If the variables were preserved between the width and height expressions, it would be somewhat shorter and easier to follow:
-vf "scale = st(0\,min(1\,gt(iw\,$FW)+gt(ih\,$FH) ) ) * (gte(a\,$FA)*$FW + lt(a\,$FA)*(($FH*iw)/ih) ) + not(ld(0))*iw : \
ld(0) * ( lte(a\,$FA)*$FH + gt(a\,$FA)*(($FW*ih)/iw) ) + not(ld(0))*ih " \

Maybe it's not that important, but I'm sure more 'global' variables would have other uses as well. In any case, unless and until such a feature is developed, it would be good to put in the manual that the variables are not preserved between expressions. Might save someone else several days of tearing their hair out! Thanks

comment:4 Changed 5 years ago by michael

good idea, ive updated the docs

comment:5 in reply to: ↑ 3 Changed 4 years ago by saste

  • Component changed from undetermined to avutil
  • Keywords scale added
  • Resolution set to wontfix
  • Status changed from new to closed

Replying to jworrall:

Oh, well, that explains a lot. It seems the variables would be more powerful if they could be shared between expressions. For example, I am trying to write a scale filter that will scale a video of any size and aspect ratio down (but not up) to fit inside an iPhone display, while preserving aspect ratio. I've written a script that gets variables for the display/frame size depending on which iPhone it is (FW, FH and the aspect ratio FA).

I was eventually able to do it without variables; it looks like this:
-vf "scale = min(1\,gt(iw\,$FW)+gt(ih\,$FH)) * (gte(a\,$FA)*$FW + lt(a\,$FA)*(($FH*iw)/ih)) + not(min(1\,gt(iw\,$FW)+gt(ih\,$FH)))*iw : \
min(1\,gt(iw\,$FW)+gt(ih\,$FH)) * (lte(a\,$FA)*$FH + gt(a\,$FA)*(($FW*ih)/iw)) + not(min(1\,gt(iw\,$FW)+gt(ih\,$FH)))*ih" \

If the variables were preserved between the width and height expressions, it would be somewhat shorter and easier to follow:
-vf "scale = st(0\,min(1\,gt(iw\,$FW)+gt(ih\,$FH) ) ) * (gte(a\,$FA)*$FW + lt(a\,$FA)*(($FH*iw)/ih) ) + not(ld(0))*iw : \
ld(0) * ( lte(a\,$FA)*$FH + gt(a\,$FA)*(($FW*ih)/iw) ) + not(ld(0))*ih " \

Maybe it's not that important, but I'm sure more 'global' variables would have other uses as well. In any case, unless and until such a feature is developed, it would be good to put in the manual that the variables are not preserved between expressions. Might save someone else several days of tearing their hair out! Thanks

Global variables would require a serious overhaul of the eval system (since you may need to pass the environment from one expression to another), and would have several possible unwanted side effects. I think the best way to achieve what you want is through external scripting, this would also simplify the logic and improve readability.

So I'm closing this feature request as WONTFIX.

Note: See TracTickets for help on using tickets.