segmentation fault when trying to read webm file
esc opened this issue · comments
I compiled lintel against ffmpeg
4.0.0 from conda-forge
. I get segfaults when trying to decode a webm
file:
(base) vhaenel@gpucluster02:~/lintel$ lintel_test --filename ../benchmarks/smth-smth-1.webm --width 0 --height 0
python: lintel/py_ext/lintelmodule.c:134: setup_vid_stream_context: Assertion `(video_stream->duration > 0) && (video_stream->nb_frames > 0)' failed.
Aborted (core dumped)
I have attached the file. To test it, please rename it to smth-smth-1.webm
.
Same problem occurs when ffmpeg
was compiled from source, following the instructions from README
.
Hmm, this one may take some digging into FFmpeg's examples to see if they handle the webm container specially.
Your video has only one stream, but for some reason that video stream has a negative value for duration, and nb_frames = 0.
Out of curiousity, is your FFmpeg compiled with --enable-libvpx? You can see this from ffmpeg -version
.
Just to add some more data points from my side: I can reproduce the error, and due to the odd-numbered width of this video (427) I can't convert the video to H.264. However, I am able to convert to PNG, so my FFmpeg's VP9 codec is working, at least.
One workaround that does work for me is to resize the video while converting to H.264/MP4 container:
ffmpeg -i smth-smth-1.webm -s 426x240 smth-smth-1.mp4
Lintel can handle the video after that. It does seem that Lintel just doesn't handle webm correctly, as even if I transcode to a new webm file, I still hit the same video_stream->nb_frames == 0
issue.
Hi All,
I was wondering if you can give this branch a try: https://github.com/dukebw/lintel/tree/webm-fix.
The problem with webm was that the container doesn't store information about either the duration or the number of frames per stream (see https://stackoverflow.com/a/32538549). So now we get duration from the AVFormatContext (instead of the AVStream), and approximate nb_frames from the average FPS.
If that branch fixes your issues, then I will merge it in. I also fixed a bug in receive_frame() (I was using the avcodec_send_packet() / avcodec_receive_frame()
API slightly wrong), which affected the VP9 encoded video you uploaded.
I get a different error then:
(base) vhaenel@gpucluster02:~/lintel$ lintel_test --filename ../benchmarks/smth-smth-1.webm --width 0 --height 0
Ran out of frames. Looping.
time: 0.312794548999932
Traceback (most recent call last):
File "/home/vhaenel/miniconda3/bin/lintel_test", line 11, in <module>
load_entry_point('Lintel==0.0', 'console_scripts', 'lintel_test')()
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/click-6.7-py3.6.egg/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/click-6.7-py3.6.egg/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/click-6.7-py3.6.egg/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/click-6.7-py3.6.egg/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/Lintel-0.0-py3.6-linux-x86_64.egg/lintel/test/loadvid_test.py", line 172, in loadvid_test
should_seek)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/Lintel-0.0-py3.6-linux-x86_64.egg/lintel/test/loadvid_test.py", line 112, in _loadvid_test_frame_nums
plt.imshow(decoded_frames[i, ...])
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 3189, in imshow
ax = gca()
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 984, in gca
return gcf().gca(**kwargs)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 601, in gcf
return figure()
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 548, in figure
**kwargs)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 161, in new_figure_manager
return cls.new_figure_manager_given_figure(num, fig)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 167, in new_figure_manager_given_figure
canvas = cls.FigureCanvas(figure)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/backends/backend_qt5agg.py", line 24, in __init__
super(FigureCanvasQTAgg, self).__init__(figure=figure)
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/backends/backend_qt5.py", line 234, in __init__
_create_qApp()
File "/home/vhaenel/miniconda3/lib/python3.6/site-packages/matplotlib/backends/backend_qt5.py", line 125, in _create_qApp
raise RuntimeError('Invalid DISPLAY variable')
RuntimeError: Invalid DISPLAY variable
I tried:
Using the patch:
(base) vhaenel@gpucluster02:~/lintel$ git diff
diff --git a/lintel/test/loadvid_test.py b/lintel/test/loadvid_test.py
index f7627fd..953456e 100644
--- a/lintel/test/loadvid_test.py
+++ b/lintel/test/loadvid_test.py
@@ -24,6 +24,7 @@ import matplotlib.pyplot as plt
import lintel
+plt.switch_backend('agg')
def _loadvid_test_vanilla(filename, width, height):
"""Tests the usual loadvid call, with a default FPS cap.
and got:
(base) vhaenel@gpucluster02:~/lintel$ lintel_test --filename ../benchmarks/smth-smth-1.webm --width 0 --height 0
Ran out of frames. Looping.
time: 0.039263828999992256
Ran out of frames. Looping.
time: 0.03922413199984476
Ran out of frames. Looping.
time: 0.03895704800015665
Ran out of frames. Looping.
time: 0.038944147999927736
Ran out of frames. Looping.
time: 0.03820108600007188
Ran out of frames. Looping.
time: 0.03833767900005114
Ran out of frames. Looping.
time: 0.03876225799990607
Ran out of frames. Looping.
time: 0.038565767000136475
Ran out of frames. Looping.
time: 0.03761931600001844
Ran out of frames. Looping.
time: 0.038617368000132046
Not sure what that means though.. Did it load it successfully?
Regarding the option you asked about:
(base) vhaenel@gpucluster02:~$ ffmpeg -version
ffmpeg: Relink `/home/vhaenel/miniconda3/bin/../lib/././libpng16.so.16' with `/lib/x86_64-linux-gnu/libpthread.so.0' for IFUNC symbol `longjmp'
ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 4.8.2 (GCC) 20140120 (Red Hat 4.8.2-15)
configuration: --prefix=/home/vhaenel/miniconda3 --disable-doc --enable-shared --enable-static --extra-cflags='-Wall -g -m64 -pipe -O3 -march=x86-64 -fPIC -I/home/vhaenel/miniconda3/include' --extra-cxxflags='=-Wall -g -m64 -pipe -O3 -march=x86-64 -fPIC' --extra-libs='-L/home/vhaenel/miniconda3/lib -lz' --enable-pic --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --enable-libfreetype --enable-gnutls --enable-libx264
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Apparently not, eh?
Hmm, it seems to be working. I believe the thing about the display variables is because you have SSH'ed into a machine without X, and lintel_test
is trying to pop up a plot. It should work with ssh -XC
.
I shall merge this change into the master branch then, thank you!
Closing as fixed by #15