0

I have this Python function that runs ffmpeg with minimal options from the Windows command line:

def run_ffmpeg(frames_path, ffmpeg_path=notebook_directory):
    '''
    This function runs ffmpeg.exe to convert PNG image files into a MP4 video.
    
    Parameters
    ----------
    frames_path : string
        Absolute path to the PNG files
    ffmpeg_path : string
        Absolute path to the FFmpeg executable (ffmpeg.exe)
    '''
    
    from subprocess import check_call
    
    
    check_call(
        [
            os.path.join(ffmpeg_path, 'ffmpeg'),
            '-y',    # Overwrite output files without asking
            '-report',    # Write logfile to current working directory
            '-framerate', '60',    # Input frame rate
            '-i', os.path.join(frames_path, 'frame%05d.png'),    # Path to input frames
            os.path.join(frames_path, 'video.mp4')    # Path to store output video
        ]
    )

When running it from a Jupyter notebook over 2500 PNG files (RGBA, ca. 600-700 kB each, 9000 x 13934 pixels), CPU usage briefly peaks to 100% before dropping to 0%, while memory usage quickly saturates to 100% and stays there, slowing the system down almost to a freeze, so I need to terminate ffmpeg from the task manager:

Screenshot

The generated video file has a size of only 48 bytes and contains just a black frame when viewed in the VLC player.

This is the ffmpeg log output:

ffmpeg started on 2022-08-05 at 17:17:55
Report written to "ffmpeg-20220805-171755.log"
Log level: 48
Command line:
"C:\\Users\\Username\\Desktop\\folder\\ffmpeg" -y -report -framerate 60 -i "C:\\Users\\Username\\Desktop\\e\\frame%05d.png" "C:\\Users\\Username\\Desktop\\e\\video.mp4"
ffmpeg version 2022-07-14-git-882aac99d2-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --ena  libavutil      57. 29.100 / 57. 29.100
  libavcodec     59. 38.100 / 59. 38.100
  libavformat    59. 28.100 / 59. 28.100
  libavdevice    59.  8.100 / 59.  8.100
  libavfilter     8. 45.100 /  8. 45.100
  libswscale      6.  8.100 /  6.  8.100
  libswresample   4.  8.100 /  4.  8.100
  libpostproc    56.  7.100 / 56.  7.100
Splitting the commandline.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Reading option '-framerate' ... matched as AVOption 'framerate' with argument '60'.
Reading option '-i' ... matched as input url with argument 'C:\Users\Username\Desktop\e\frame%05d.png'.
Reading option 'C:\Users\Username\Desktop\e\video.mp4' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option y (overwrite output files) with argument 1.
Applying option report (generate a report) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input url C:\Users\Username\Desktop\e\frame%05d.png.
Successfully parsed a group of options.
Opening an input file: C:\Users\Username\Desktop\e\frame%05d.png.
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00000.png' for reading
[file @ 0000000000425680] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042d800] Statistics: 668318 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00001.png' for reading
[file @ 000000000042dac0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042d6c0] Statistics: 668371 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00002.png' for reading
[file @ 000000000042d6c0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042dac0] Statistics: 669177 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00003.png' for reading
[file @ 000000000042dac0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0000000000437a40] Statistics: 684594 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00004.png' for reading
[file @ 0000000000437a40] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0000000000437c00] Statistics: 703014 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00005.png' for reading
[file @ 0000000000437c00] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0000000000437d00] Statistics: 721604 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00006.png' for reading
[file @ 0000000000437cc0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0000000000437f40] Statistics: 739761 bytes read, 0 seeks
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00007.png' for reading
[file @ 0000000000437f40] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0000000000438040] Statistics: 757327 bytes read, 0 seeks
[image2 @ 000000000041ff80] Probe buffer size limit of 5000000 bytes reached
Input #0, image2, from 'C:\Users\Username\Desktop\e\frame%05d.png':
  Duration: 00:00:41.67, start: 0.000000, bitrate: N/A
  Stream #0:0, 8, 1/60: Video: png, rgba(pc), 9000x13934 [SAR 29528:29528 DAR 4500:6967], 60 fps, 60 tbr, 60 tbn
Successfully opened the file.
Parsing a group of options: output url C:\Users\Username\Desktop\e\video.mp4.
Successfully parsed a group of options.
Opening an output file: C:\Users\Username\Desktop\e\video.mp4.
[file @ 000000002081e3c0] Setting default whitelist 'file,crypto,data'
Successfully opened the file.
detected 12 logical cores
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00008.png' for reading
[file @ 00000000024ad980] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 00000000004379c0] Statistics: 767857 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00009.png' for reading
[file @ 000000000042d600] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 00000000004379c0] Statistics: 774848 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00010.png' for reading
[file @ 00000000004379c0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042da00] Statistics: 787178 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00011.png' for reading
[file @ 00000000004379c0] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042da00] Statistics: 797084 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00012.png' for reading
[file @ 0000000000437a80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000042da00] Statistics: 802870 bytes read, 0 seeks
[graph 0 input from stream 0:0 @ 00000000208bf800] Setting 'video_size' to value '9000x13934'
[graph 0 input from stream 0:0 @ 00000000208bf800] Setting 'pix_fmt' to value '26'
[graph 0 input from stream 0:0 @ 00000000208bf800] Setting 'time_base' to value '1/60'
[graph 0 input from stream 0:0 @ 00000000208bf800] Setting 'pixel_aspect' to value '29528/29528'
[graph 0 input from stream 0:0 @ 00000000208bf800] Setting 'frame_rate' to value '60/1'
[graph 0 input from stream 0:0 @ 00000000208bf800] w:9000 h:13934 pixfmt:rgba tb:1/60 fr:60/1 sar:29528/29528
[format @ 00000000025ef840] Setting 'pix_fmts' to value 'yuv420p|yuvj420p|yuv422p|yuvj422p|yuv444p|yuvj444p|nv12|nv16|nv21|yuv420p10le|yuv422p10le|yuv444p10le|nv20le|gray|gray10le'
[auto_scale_0 @ 00000000025efe40] w:iw h:ih flags:'' interl:0
[format @ 00000000025ef840] auto-inserting filter 'auto_scale_0' between the filter 'Parsed_null_0' and the filter 'format'
[AVFilterGraph @ 000000000042da00] query_formats: 4 queried, 3 merged, 1 already done, 0 delayed
[auto_scale_0 @ 00000000025efe40] picking yuv444p out of 13 ref:rgba alpha:1
[auto_scale_0 @ 00000000025efe40] w:9000 h:13934 fmt:rgba sar:29528/29528 -> w:9000 h:13934 fmt:yuv444p sar:1/1 flags:0x0
[auto_scale_0 @ 00000000025efe40] w:9000 h:13934 fmt:rgba sar:29528/29528 -> w:9000 h:13934 fmt:yuv444p sar:1/1 flags:0x0
[auto_scale_0 @ 00000000025efe40] w:9000 h:13934 fmt:rgba sar:29528/29528 -> w:9000 h:13934 fmt:yuv444p sar:1/1 flags:0x0
[auto_scale_0 @ 00000000025efe40] w:9000 h:13934 fmt:rgba sar:29528/29528 -> w:9000 h:13934 fmt:yuv444p sar:1/1 flags:0x0
[libx264 @ 000000002081d280] using mv_range_thread = 376
[libx264 @ 000000002081d280] using SAR=1/1
[libx264 @ 000000002081d280] frame MB size (563x871) > level limit (139264)
[libx264 @ 000000002081d280] DPB size (4 frames, 1961492 mbs) > level limit (1 frames, 696320 mbs)
[libx264 @ 000000002081d280] MB rate (29422380) > level limit (16711680)
[libx264 @ 000000002081d280] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 000000002081d280] profile High 4:4:4 Predictive, level 6.2, 4:4:4, 8-bit
[libx264 @ 000000002081d280] 264 - core 164 r3095 baee400 - H.264/MPEG-4 AVC codec - Copyleft 2003-2022 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=18 lookahead_threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 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, mp4, to 'C:\Users\Username\Desktop\e\video.mp4':
  Metadata:
    encoder         : Lavf59.28.100
  Stream #0:0, 0, 1/15360: Video: h264 (avc1 / 0x31637661), yuv444p(tv, progressive), 9000x13934 [SAR 1:1 DAR 4500:6967], q=2-31, 60 fps, 15360 tbn
    Metadata:
      encoder         : Lavc59.38.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
Clipping frame in rate conversion by 0.000008
frame=    1 fps=0.8 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00013.png' for reading
[file @ 000000000a6a2180] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 810395 bytes read, 0 seeks
frame=    2 fps=0.8 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00014.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 818213 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00015.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 817936 bytes read, 0 seeks
frame=    4 fps=1.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00016.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 817014 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00017.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 828088 bytes read, 0 seeks
frame=    6 fps=1.5 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00018.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 831007 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00019.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 845203 bytes read, 0 seeks
frame=    8 fps=1.7 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00020.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 851548 bytes read, 0 seeks
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00021.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 847629 bytes read, 0 seeks
frame=   10 fps=1.8 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00022.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 860169 bytes read, 0 seeks
frame=   11 fps=1.4 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00023.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 857243 bytes read, 0 seeks
frame=   12 fps=1.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[image2 @ 000000000041ff80] Opening 'C:\Users\Username\Desktop\e\frame00024.png' for reading
[file @ 000000001ec86c80] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 000000000b38de80] Statistics: 835155 bytes read, 0 seeks

What is the problem?

By the way, the color model of the image files was confirmed by doing

from PIL import Image


img = Image.open('C:\\Users\\EPI-SMLM\\Desktop\\e\\frame00000.png')
img.mode
-------------------------------------------------------------------
C:\Program Files\Python38\lib\site-packages\PIL\Image.py:3035: DecompressionBombWarning: Image size (125406000 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  warnings.warn(

'RGBA'

The "decompression bomb warning" appears to be a false alarm/bug.

UPDATE: I can confirm that this happens even when there are only 50 image files, i.e. 50 x 700 kB = 35 MB in total size. ffmpeg still gobbles up all available memory (almost 60 GB of private bytes!!!).

And it also happens if ffmpeg is run from the command line.

This must be a bug!

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy