Opened 13 years ago

Closed 12 years ago

#732 closed enhancement (wontfix)

Storing variables not working in expressions

Reported by: Jim 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 by Jim, 13 years ago

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 by Michael Niedermayer, 13 years ago

Type: defectenhancement

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

in reply to:  2 ; comment:3 by Jim, 13 years ago

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 by Michael Niedermayer, 13 years ago

good idea, ive updated the docs

in reply to:  3 comment:5 by Stefano Sabatini, 12 years ago

Component: undeterminedavutil
Keywords: scale added
Resolution: wontfix
Status: newclosed

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.