Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#5222 closed defect (invalid)

ffmpeg crashing for large "-filter_complex_script" inputs

Reported by: jsniff Owned by:
Priority: important Component: undetermined
Version: git-master Keywords: ffmpeg, video, crash
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description (last modified by Elon Musk)

We're experiencing an issue where ffmpeg seg faults for very large "-filter_complex_script" input files (roughly 3MB). The input file consists of a very large number of drawbox filters. The same processing pipeline works fine for smaller files, but seems to have an issue as the file size increases. Is there a hard limit to how large this file can be? If so, is there a "magic number" somewhere that we can increase and re-compile from source?

Does anyone have any other thoughts or advice?

Thanks in advance!

Change History (45)

comment:1 by Elon Musk, 8 years ago

Description: modified (diff)
Summary: ffmpeg crashing for large “-filter_complex_script” inputsffmpeg crashing for large "-filter_complex_script" inputs

Please provide such files.
There should not be limit.

comment:2 by jsniff, 8 years ago

I will post such files in a few hrs.

comment:3 by Elon Musk, 8 years ago

Reproduced by developer: set
Status: newopen
Version: unspecifiedgit-master

comment:4 by jsniff, 8 years ago

Here is filter file: https://www.dropbox.com/s/2fdbsc810qxsxyf/video_filters.1454607985?dl=0
We are using ffmpeg version 2.7.2. The video file is sensitive for us to release, but we've confirmed that for this particular filter file, the seg fault seems to occur with any video file, as long as there are more than 69,700 frames (the filters file references frames up to that point).
Let me know your experience!

comment:5 by Elon Musk, 8 years ago

This is certainly the wrong and inefficient way to do it. I will write filter which will read new filtergraph from each line of file.

So you would only need to change this script to split each drawbox into separate line and move enable option in front of line, something like this:

0,0 drawbox=......... # filter 0th frame
1,5 drawbox=......... # filter 1-5 frames

etc.

comment:6 by jsniff, 8 years ago

Thanks for your help. We’re open to any solution that you would propose. Fundamentally, the boxes need to change each frame. They seldom stay in the same place from frame to frame. So if the seg fault is due to the number of boxes being drawn, simply extending the boxes for multiple frames might not reduce the amount of input that ffmpeg is processing

comment:7 by mbradshaw, 8 years ago

Resolution: invalid
Status: openclosed

You're getting a stack overflow from generating so many stack frames from all your nested filters[1].

This isn't a bug in FFmpeg, but instead a limitation of your computer. I'm closing as invalid.

[1]: http://stackoverflow.com/questions/35258868/ffmpeg-crashes-for-large-filter-complex-script-inputs#comment58235562_35258868

comment:8 by Elon Musk, 8 years ago

I wrote filter that reads filter graphs from input file, with it you can define millions of lines in file with something like this:

ffmpeg -i input.video -vf graphhint=graphs.txt output.video

Where graphs.txt is textual file consisting of lines like this:

0,0 drawbox=x=5:y=2:w=3:h=5
1,1 drawbox=x=6:y=3:w=4:h=5
2,22 drawbox=...

you get an idea, the '0,0' part means frames in range 0 to 0.

comment:9 by jsniff, 8 years ago

@richardpl I am trying that approach now

comment:10 by Clément Bœsch, 8 years ago

The script works for me here (memory consumption is about +200M). Can you provide a gdb backtrace?

BTW, you can use enable='eq(n,123)' instead of enable='between(n,123,123)'

comment:11 by jsniff, 8 years ago

@ubitux

what script? what command did you use? I'm trying @richardpl's approach now.

Last edited 8 years ago by jsniff (previous) (diff)

comment:12 by Clément Bœsch, 8 years ago

I used ffmpeg -f lavfi -i color=white:s=hd720 -filter_script video_filters.1454607985 -c:v ffv1 -y out.nut (and stopped manually after about 2 minutes of encoded video.

richarpl's approach is probably better, but it shouldn't crash.

comment:13 by jsniff, 8 years ago

@richardpl whenever i run your command, I get the error, No such filter: 'graphhint'. How can I get such a filter?

Last edited 8 years ago by jsniff (previous) (diff)

comment:14 by Elon Musk, 8 years ago

@jsniff: its patch on ffmpeg-devel, not yet pushed upstream.

comment:15 by jsniff, 8 years ago

@richardpl So it's not possible to test?

comment:16 by Elon Musk, 8 years ago

It is possible to test, just need to download patch, apply it and reconfigure and rebuild ffmpeg.

comment:18 by Elon Musk, 8 years ago

@jsniff yes

comment:19 by jsniff, 8 years ago

@richardpl great. i will try now.

comment:20 by jsniff, 8 years ago

@richardpl, if you don't mind me asking, how do you apply the patch? I stripped away that .patch file until the diff at beginning and the -- at the end.
I tried following some advice at links below after some googling, but it doesn't work for me. eg, patch -pl < attachment.patch results in " strip count l is not a number". Where attachment.patch is the file stripped down at the above link.

https://github.com/vivienschilis/ffmpeg-head

http://tipok.org.ua/node/24

comment:21 by Elon Musk, 8 years ago

If you have git installed use: git apply attachment.patch in ffmpeg directory.

patch -p1 < attachment.patch works to, note it is 1 and not l.

comment:22 by jsniff, 8 years ago

@richardpl I don't have git installed. Is there another way? Also, for ffmpeg directory. You mean I have to put patch file in same directory as where "which ffmpeg" directory is?

Last edited 8 years ago by jsniff (previous) (diff)

comment:23 by Elon Musk, 8 years ago

patch doeesn need to be in same directory, but can be for shorter command,
so put patch in ffmpeg directory and run this:

patch -p1 < attachment.patch

comment:24 by jsniff, 8 years ago

@richardpl, I have installed git. But when I do that, I get following errors:

error: doc/filters.texi: No such file or directory
error: libavfilter/Makefile: No such file or directory
error: libavfilter/allfilters.c: No such file or directory

When I just do patch -p1 < attachment.patch, without git, I get following error:

can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:


|diff --git a/doc/filters.texi b/doc/filters.texi
|index 8ae402a..241ded0 100644

a/doc/filters.texi

|+++ b/doc/filters.texi

comment:26 by jsniff, 8 years ago

@richardpl, that installs fine. However, when I type ffmpeg -filters, graphhint does not show up as a filter......it did show up in two places in logs of installation. Do I have to enable, the enabled filter in someway?

  1. Enabled filters:

graphhint

  1. CC libavfilter/vf_graphhint.o

./configure --enable-filter=graphhint

comment:27 by Elon Musk, 8 years ago

dont forget to install it or use ./ffmpeg

comment:28 by jsniff, 8 years ago

@richardpl, I guess I forgot ./configure --enable-filter=graphhint when installing initially.

comment:29 by jsniff, 8 years ago

@richarpl, so I just did that, then make, then make install, and graphhint is still not installed. Do I have to do something differently?

comment:30 by Elon Musk, 8 years ago

Perhaps it is installed in another directory, and you use still use old ffmpeg.
so start it with ./ffmpeg ....

comment:31 by llogan, 8 years ago

You should consider getting live help at the #ffmpeg IRC channel to figure out how to apply the patch, compiling, etc. That way you don't spam the ffmpeg-trac mailing list with dozens of back-and-forth comments.

comment:32 by jsniff, 8 years ago

@richardpl, ok, your code runs fine, but output doesn't display boxes. For your example, I added color before and after the below, but it didn't have any effect. So, what should I do for color?

0,0 drawbox=x=5:y=2:w=3:h=5
1,1 drawbox=x=6:y=3:w=4:h=5

comment:33 by Elon Musk, 8 years ago

just add ':color=invert' after h=5 make sure there is no spaces, because they are not ignored for now and they do breaks parsing.

comment:34 by jsniff, 8 years ago

@richardpl, when i do the below, there is no output.

0,0 drawbox=x=5:y=2:w=3:h=5:color=invert
1,1 drawbox=x=6:y=3:w=4:h=5:color=invert

what i think you mean is the below, but the below has no output as well......

0,0 drawbox=x=5:y=2:w=3:h=5:color=gray
1,1 drawbox=x=6:y=3:w=4:h=5:color=gray

comment:35 by Elon Musk, 8 years ago

How you test it? What is ffmpeg output?
It works fine here.

comment:36 by jsniff, 8 years ago

@richardpl, actually this works fine now. How did you fill the box though? What if you want a solid box? I will stress test it now for long videos.

comment:37 by Elon Musk, 8 years ago

add ':t=max'

comment:38 by jsniff, 8 years ago

@richardpl ya this works, i will stress-test for a few hours and let you know my thoughts. thanks!

comment:39 by jsniff, 8 years ago

@richardpl, does your framework allow for writing multiple boxes on one frame? It seems not to be working for me right now. When I do something like the below, the gray box shows up until frame 100, then the red box shows up until frame 200, then the blue box from frame 200 to 300. But the red box and blue box should have shown up before that.....

10,100 drawbox=x=13:y=14:w=15:h=16:color=gray:t=max
1,200 drawbox=x=60:y=34:w=35:h=36:color=red:t=max
1,300 drawbox=x=80:y=24:w=35:h=36:color=blue:t=max


comment:40 by jsniff, 8 years ago

@richardpl, I've tried a few variants. It's still doesn't allow for multiple boxes on an image. If you have any thoughts, please let me know.

comment:41 by Elon Musk, 8 years ago

For other boxes with overlapping frames you will need another file with lines and new graphhint instance.

I don't see how to do all them in same file.

So gray boxes would be in 1st file, red boxes in 2nd file and blue boxes in 3rd file, and any other boxes in next file.

-vf graphhint=gray.txt,graphhint=red.txt,graphhint=blue.txt ...

I also wrote luascript filter which would tehnically allow this in single file but script size would be even longer and parsing would be slower than graphhint approach.

comment:42 by jsniff, 8 years ago

@richardpl,

That works well. One other question/problem. Often times, my filter file is very long and has duplicate boxes of same color on same frame. So essentially, with your approach, you're asking me to break up the large file into several (possibly hundred or thousands) of text files. Is there another way to get around this? Possibly with luascript filter?

comment:43 by Elon Musk, 8 years ago

Nope, you still can do it in one file, but its more complicated, lets take your example above:

10,100 drawbox=x=13:y=14:w=15:h=16:color=gray:t=max
1,200 drawbox=x=60:y=34:w=35:h=36:color=red:t=max
1,300 drawbox=x=80:y=24:w=35:h=36:color=blue:t=max

It translates to this:

1,9 drawbox=x=60:y=34:w=35:h=36:color=red:t=max,drawbox=x=80:y=24:w=35:h=36:color=blue:t=max
10,100 drawbox=x=13:y=14:w=15:h=16:color=gray:t=max,drawbox=x=80:y=24:w=35:h=36:color=blue:t=max,drawbox=x=60:y=34:w=35:h=36:color=red:t=max
101,200 drawbox=x=60:y=34:w=35:h=36:color=red:t=max,drawbox=x=80:y=24:w=35:h=36:color=blue:t=max
201,300 drawbox=x=80:y=24:w=35:h=36:color=blue:t=max

comment:44 by jsniff, 8 years ago

@richardpl,

That works well. I just need to do some manipulating of original file then. I will stress test a bit more and let you know.

comment:45 by jsniff, 8 years ago

@richardpl,

I've done some stress-testing. This works well so far. Thanks! I'll keep you posted about it.

Note: See TracTickets for help on using tickets.