Opened 14 months ago

Last modified 13 months ago

#5799 new defect

Memory psudo-leak when FF_API_CODED_FRAME enabled

Reported by: DeHackEd Owned by:
Priority: important Component: avcodec
Version: git-master Keywords: cc oom
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:
How to reproduce:

% ffmpeg -i verylargefile.ts -c:v mpeg2video -c:a ac3 -b:a 384k -muxrate 4.50M -b:v 3.75M -maxrate:v 3.75M -minrate:v 1.00M -bufsize:v 1000k -flags ildct -vf interlace -s 640:480 -f mpegts -map 0:0 -map 0:1  udp://239.255.255.1:1234

Git version 500662784341373d625af629cad94826beca3bc8 tested

Valgrind reports the following stack trace consuming memory for each frame:

==19806== 195,744 bytes in 8,156 blocks are still reachable in loss record 694 of 731
==19806==    at 0x4A05588: memalign (vg_replace_malloc.c:727)
==19806==    by 0x4A05623: posix_memalign (vg_replace_malloc.c:876)
==19806==    by 0xC98A99: av_mallocz (mem.c:97)
==19806==    by 0xC8A2F9: av_buffer_alloc (buffer.c:48)
==19806==    by 0xC92195: frame_copy_props (frame.c:636)
==19806==    by 0x6A2E04: ff_mpv_encode_picture (mpegvideo_enc.c:1738)
==19806==    by 0x7178EE: avcodec_encode_video2 (utils.c:1961)
==19806==    by 0x459049: do_video_out (ffmpeg.c:1176)
==19806==    by 0x459FA0: reap_filters (ffmpeg.c:1367)
==19806==    by 0x45E59B: main (ffmpeg.c:4114)

The memory allocation will be cleaned up eventually on shutdown -- valgrind will not report a true memory leak -- but while ffmpeg is running memory usage will grow over time. Very long runs (well over 24 hours) will consume gigabytes of RAM.

Editing libavcodec/version.h to force FF_API_CODED_FRAME to 0 appears to fix the issue.

Change History (11)

comment:1 Changed 14 months ago by cehoyos

  • Keywords coded_frame leak removed

Please provide the command line that allows to reproduce the issue together with the complete, uncut console output to make this a valid ticket.

comment:2 Changed 14 months ago by DeHackEd

Very well. I also simplified the command-line a bit. I resize the video so that the encoding process will go faster.

$ cat w*.ts | ffmpeg-stock -f mpegts -i - -c:v mpeg2video -s 320x240 -b 5M -map 0:v -f mpegts -y /dev/null
ffmpeg version N-81456-g5006627 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
  configuration: --disable-filters --enable-filter='acrossfade,adelay,adrawgraph,aecho,aevalsrc,aeval,afade,aformat,aloop,anull,amerge,amix,anull,anullsrc,anullsink,aresample,asetps,asetrate,asplit,blackdetect,blend,channelmap,channelsplit,chorus,extrastereo,concat,crop,cropdetect,delogo,deshake,detelecine,drawbox,drawtext,fade,field,format,framestep,framepack,interlace,interleve,null,nullsink,nullsrc,overlay,pan,pp,pullup,psnr,setfield,setpts,scale,settb,split,spp,telecine,volume,volumedetect,yadif' --disable-demuxers --enable-demuxer='aac,ac3,asf,avi,concat,dts,dv*,eac3,flv,g*,h264,hevc,hls,image2,m4v,matroska,mjpeg,mov,mp3,mpegps,mpets,mpegtsraw,mpegvideo,ogg,pcm*,rawvideo,rtsp,wav,webm*' --disable-muxers --enable-muxer='ac3,apng,af2,avi,dash,dv,eac3,flv,h264hevc,hls,mat*,mjpeg,md5,mov,mp3,mp4,mpeg*,ogg,opus,pcm*,rawvideo,wav,webm*' --disable-encoders --enable-encoder='mpeg2video,mpeg1video,ac3*,adpcm*,pcm*,aac,mjpeg,libfdk_aac,libx26*' --disable-decoders --enable-decoder='aac,aac_fixed,ac3,ac3_fixed,adpcm*,bmp,dvaudio,dvsub,eac3*,gif,gsm,flv,ffv*,hevc,h26*,mjpeg,mp*,opus,pcm*,png,ppm,snow,theora,text,vc1,vp8,vp9,wmc*' --enable-libx264 --extra-cflags='-gdwarf-2 -I/home/sean/src/GIT/x264 -march=core2' --extra-ldflags='-L/home/sean/src/GIT/x264 -lstdc++' --enable-gpl --extra-ldflags=-ldl --enable-libfdk-aac --enable-nonfree --disable-vdpau --disable-outdevs --disable-hwaccels --disable-indevs --disable-lzma --disable-bzlib --disable-zlib --disable-libx265
  libavutil      55. 29.100 / 55. 29.100
  libavcodec     57. 54.100 / 57. 54.100
  libavformat    57. 48.100 / 57. 48.100
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 55.100 /  6. 55.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] SPS unavailable in decode_picture_timing
[h264 @ 0x1a58ee0] non-existing PPS 0 referenced
[h264 @ 0x1a58ee0] decode_slice_header error
[h264 @ 0x1a58ee0] no frame!
Input #0, mpegts, from 'pipe:':
  Duration: N/A, start: 16129.943311, bitrate: N/A
  Program 1 
    Stream #0:0[0x1e1]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
    Stream #0:1[0x1e2](eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 320 kb/s
    Stream #0:2[0x1e4](enm): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 64 kb/s (visual impaired)
Please use -b:a or -b:v, -b is ambiguous
[mpeg2video @ 0x1aad5c0] too many threads/slices (16), reducing to 15
[mpegts @ 0x1abdc00] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, mpegts, to '/dev/null':
  Metadata:
    encoder         : Lavf57.48.100
    Stream #0:0: Video: mpeg2video (Main), yuv420p, 320x240 [SAR 4:3 DAR 16:9], q=2-31, 5000 kb/s, 59.94 fps, 90k tbn, 59.94 tbc
    Metadata:
      encoder         : Lavc57.54.100 mpeg2video
    Side data:
      cpb: bitrate max/min/avg: 0/0/5000000 buffer size: 0 vbv_delay: -1
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mpeg2video (native))
[h264 @ 0x1ac57e0] co located POCs unavailable
^Cframe=145785 fps=349 q=2.0 Lsize= 1140321kB time=00:40:32.41 bitrate=3840.4kbits/s speed=5.82x    
video:1039833kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 9.663832%
Exiting normally, received signal 2.

Memory usage near the start:

$ grep VmRSS /proc/61027/status
VmRSS:	  137252 kB

20 minute mark:

$ grep VmRSS /proc/61027/status
VmRSS:	  170440 kB

40 minute mark:

$ grep VmRSS /proc/61027/status
VmRSS:	  201296 kB

Times are approximate.

I discussed this briefly in #ffmpeg-devel with Btbn. It looks like a huge chain of side data are being added to the coded_frame field and not being cleaned up as it goes, at least until shutdown.

comment:3 Changed 13 months ago by cehoyos

  • Keywords cc added

Is this also reproducible if the input stream does not contain Closed Captions?

comment:4 Changed 13 months ago by DeHackEd

Closed Captions are mandatory for the issue to manifest.

Given the nature of the bug, in theory any SIDE_DATA would suffice but this is the only way I tested it.

comment:5 Changed 13 months ago by cehoyos

  • Keywords oom added

comment:6 Changed 13 months ago by oromit

This is caused by the following line:
https://github.com/FFmpeg/FFmpeg/blob/5a70e56f2/libavcodec/mpegvideo_enc.c#L1738

which ends up here:
https://github.com/FFmpeg/FFmpeg/blob/5a70e56f2/libavutil/frame.c#L331

Which in turn appends the new side data in this function:
https://github.com/FFmpeg/FFmpeg/blob/5a70e56f2/libavutil/frame.c#L617

So what is happening here is that inside of the coded_frame, all side data is just endlessly appended, until av_frame_new_side_data eventually runs out of memory to realloc all that side data.

A simple fix might be calling av_frame_unref(s->avctx->coded_frame) before av_frame_copy_props in mpegvideo_enc.c.

comment:7 Changed 13 months ago by oromit

CLI without any external inputs:

./ffmpeg -f lavfi -i testsrc2 -vf mestimate -c:v mpeg2video -f null -

comment:8 Changed 13 months ago by cehoyos

Is this a regression?
Sorry, my dvb providers do not send Closed Captions, and the filter is very new.
(I am willing to test myself if you can provide a long sample.)

comment:9 Changed 13 months ago by oromit

Didn't test, but judging from a quick git blame it might be once since d6604b29ef544793479d7fb4e05ef6622bb3e534

comment:10 follow-up: Changed 13 months ago by cehoyos

  • Component changed from undetermined to avcodec
  • Priority changed from normal to important

Fixed by Timo Rothenpieler in 99b823f0a1be42abc0f3a6a0da946c4464db5fb6
Should not be closed until properly backported, I don't know which/if releases are affected.
(I am still willing to test with appropriate samples.)

Last edited 13 months ago by cehoyos (previous) (diff)

comment:11 in reply to: ↑ 10 Changed 13 months ago by heleppkes

As mentioned above, the issue did appear with d6604b29ef544793479d7fb4e05ef6622bb3e534, which is in 2.8 and newer.

Last edited 13 months ago by heleppkes (previous) (diff)
Note: See TracTickets for help on using tickets.