mastodon / mastodon

Your self-hosted, globally interconnected microblogging community
https://joinmastodon.org
GNU Affero General Public License v3.0
47.11k stars 6.98k forks source link

ffmpeg crashes when higher-than-wide GIF is uploaded as pfp #32865

Open seano-vs opened 1 day ago

seano-vs commented 1 day ago

Steps to reproduce the problem

  1. Run mastodon in docker/k8s
  2. try and upload this (attached) file as a pfp

Image

  1. 500 error, with ffmpeg on the backend crashing

Also, side note: if I run this gif through a png converter it uploads just fine

Expected behaviour

the gif can be uploaded

Actual behaviour

user sees a 500

Detailed description

logs:

[2024-11-12T14:37:27.314178 #19] ERROR -- : [22f707d3-a75a-4b92-86ba-b34dc8fe1c34]   
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] Paperclip::Error (Error while optimizing 92a1c954cb258bcbc1b126bf10cf9be820241112-19-xectsq: Command 'ffmpeg -nostdin -i '/tmp/92a1c954cb258bcbc1b126bf10cf9be820241112-19-xectsq.gif' -map_metadata -1 -fpsmax '60' -frames:v '3000' -filter_complex 'scale=iw:ih:force_original_aspect_ratio=increase,crop=ih:ih,split[a][b];[a]palettegen=max_colors=32[p];[b][p]paletteuse=dither=bayer' -y '/tmp/b4a2fb7a116512b3a1a479cc46cacd1820241112-19-y9clmr.gif'' returned 234. Expected 0
Here is the command output: STDOUT:

STDERR:

ffmpeg version 7.0.2 Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 12 (Debian 12.2.0-14)
  configuration: --prefix=/usr/local/ffmpeg --toolchain=hardened --disable-debug --disable-devices --disable-doc --disable-ffplay --disable-network --disable-static --enable-ffmpeg --enable-ffprobe --enable-gpl --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-shared --enable-version3
  libavutil      59.  8.100 / 59.  8.100
  libavcodec     61.  3.100 / 61.  3.100
  libavformat    61.  1.100 / 61.  1.100
  libavdevice    61.  1.100 / 61.  1.100
  libavfilter    10.  1.100 / 10.  1.100
  libswscale      8.  1.100 /  8.  1.100
  libswresample   5.  1.100 /  5.  1.100
  libpostproc    58.  1.100 / 58.  1.100
Input #0, gif, from '/tmp/92a1c954cb258bcbc1b126bf10cf9be820241112-19-xectsq.gif':
  Duration: 00:00:00.10, start: 0.000000, bitrate: 2002 kb/s
  Stream #0:0: Video: gif, bgra, 228x286, 10 fps, 100 tbr, 100 tbn
Stream mapping:
  Stream #0:0 (gif) -> scale:default
  paletteuse:default -> Stream #0:0 (gif)
[Parsed_crop_1 @ 0x564aa6618100] Invalid too big or non positive size for width '286' or height '286'
[Parsed_crop_1 @ 0x564aa6618100] Failed to configure input pad on Parsed_crop_1
[fc#0 @ 0x564aa6618240] Error reinitializing filters!
[fc#0 @ 0x564aa6618240] Task finished with error code: -22 (Invalid argument)
[vost#0:0/gif @ 0x564aa661ce40] Could not open encoder before EOF
[vost#0:0/gif @ 0x564aa661ce40] Task finished with error code: -22 (Invalid argument)
[vost#0:0/gif @ 0x564aa661ce40] Terminating thread with return code -22 (Invalid argument)
[fc#0 @ 0x564aa6618240] Terminating thread with return code -22 (Invalid argument)
[out#0/gif @ 0x564aa661c380] Nothing was written into output file, because at least one of its streams received no packets.
frame=    0 fps=0.0 q=0.0 Lsize=       0KiB time=N/A bitrate=N/A speed=N/A    
Conversion failed!
):
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34]   
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/vips_lazy_thumbnail.rb:72:in `rescue in make'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/vips_lazy_thumbnail.rb:35:in `make'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/attachment_extensions.rb:21:in `block in post_process_style'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/attachment_extensions.rb:20:in `each'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/attachment_extensions.rb:20:in `inject'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/paperclip/attachment_extensions.rb:20:in `post_process_style'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] app/services/update_account_service.rb:8:in `call'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] app/controllers/settings/profiles_controller.rb:11:in `update'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] app/controllers/concerns/localized.rb:11:in `set_locale'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/mastodon/rack_middleware.rb:9:in `call'
[22f707d3-a75a-4b92-86ba-b34dc8fe1c34] lib/public_file_server_middleware.rb:18:in `call'

Mastodon instance

masto.nyc

Mastodon version

v4.3.1

Technical details

Infra: https://github.com/Five-Borough-Fedi-Project/masto.nyc-docean/tree/main

renchap commented 1 day ago

We treat animated GIFs as a special case in the code as libvips does not support resizing them and they are processed with ffmpeg instead.

That is probably because the gif is not square (228x286 according to ffmpeg) and our code forces ffmpeg height and width to be a square of the larger dimension (286x286), resulting in this error:

Invalid too big or non positive size for width '286' or height '286'

I am not sure why this is happening, as our code seems to pick the smallest dimension, so I dont understand why it passes 286 as the height and width to ffmpeg: https://github.com/mastodon/mastodon/blob/main/lib/paperclip/vips_lazy_thumbnail.rb#L54

ClearlyClaire commented 5 hours ago

I am not sure why this is happening, as our code seems to pick the smallest dimension

It picks the smallest between target_width and target_height, but in this case, those are not numeric values but iw and ih: https://github.com/mastodon/mastodon/blob/766358e52b86ca0dc6cf9bb091565e97af00b19a/lib/paperclip/vips_lazy_thumbnail.rb#L41-L43

I am slightly confused by this part of the code so I'm not completely sure what we should do here.