Opened 10 months ago

Last modified 9 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 10 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 10 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 9 months ago by cehoyos

  • Keywords cc added

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

comment:4 Changed 9 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 9 months ago by cehoyos

  • Keywords oom added

comment:6 Changed 9 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 9 months ago by oromit

CLI without any external inputs:

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

comment:8 Changed 9 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 9 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 9 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 9 months ago by cehoyos (previous) (diff)

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

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

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