Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ugoira conversion: ffmpeg process sometimes becomes stopped on linux, making gallery-dl hang #2296

Closed
thatfuckingbird opened this issue Feb 13, 2022 · 4 comments

Comments

@thatfuckingbird
Copy link
Contributor

thatfuckingbird commented Feb 13, 2022

On some ugoiras, the ffmpeg process can become "stopped" on Linux, making gallery-dl hang and never finish the conversion. It does not seem to be reliably reproducable, but I think I found the root cause.

My ugoira postprocessor config:

        "postprocessors": [
            {
                "name": "ugoira",
                "whitelist": ["pixiv", "danbooru"],
                "keep-files": true,
                "ffmpeg-twopass": false,
                "ffmpeg-args": ["-c:v", "libvpx-vp9", "-lossless", "1", "-pix_fmt", "yuv420p", "-y"]
            }
        ],

On my PC, the problem occurs on this ugoira:
https://www.pixiv.net/en/artworks/88748768

Looking in the process manager, I see that the process has become "stopped" for some reason (gallery-dl is called from another Python script here, from a thread started with daemon=True, which might or might not be relevant):
image

Attaching to it with strace, I get:

strace: Process 9670 attached
--- stopped by SIGTTOU ---

I redirect the output of gallery-dl, and thus ffmpeg, into a file, which ends like this when the hang occurs:

[postprocessor.ugoira][debug] ffmpeg args: ['ffmpeg', '-f', 'concat', '-i', '/tmp/tmpybgs_xxe/ffconcat.txt', '-r', '1000/40', '-c:v', 'libvpx-vp9', '-lossless', '1', '-pix_fmt', 'yuv420p', '-y']
ffmpeg version n5.0 Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 11.1.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librav1e --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-shared --enable-version3
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100

Nothing obviously wrong here.

Looking up SIGTTOU:

SIGTTOU
This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. Again, the default action is to stop the process. SIGTTOU is only generated for an attempt to write to the terminal if the TOSTOP output mode is set; see Output Modes.

Can't say I fully understand, but seems like it has to do with writing to the terminal. However, ffmpeg-output is set to true (the default) in the gallery-dl config, which means it will be redirected to gallery-dl's stdout, which I redirect to a file.
However, further searching I find that:

ffmpeg enables interaction with stdin by default. (See documentation on its -stdin option.) On Mac OS X and Linux systems, this causes an ffmpeg job running in the background to suspend, though oddly with a message about "tty output" rather than "tty input".

So I try adding -nostdin to the ffmpeg args in gallery-dl config, and the issue seems to be fixed. If I remove it, ffmpeg hangs again.
So this seems to be the root cause. I have no idea what ffmpeg is trying to do with stdin, especially that I don't see any prompt in the stdout, but adding this option fixed it, whatever it was. I think it should be part of the default config.

Update
On another PC, the above -nostdin fix was not enough. We tried various things like turning off job control and playing around with tty flags that should have prevented SIGTTOU, but for some reason none of it helped. Something must be different in the configuration between systems, but I do not know what, or even why these signals were sent.
What ended up helping in the end is adding
signal.signal(signal.SIGTTOU, signal.SIG_IGN) to the script that starts gallery-dl (I guess this is then inherited by child processes). This is a more drastic solution than the ffmpeg flag above, but I think it might still be worth adding to gallery-dl itself, probably behind a configuration flag (and also doing the same for SIGTTIN).

@mikf
Copy link
Owner

mikf commented Feb 13, 2022

Have you tried adding stdin=subprocess.DEVNULL to the ffmpeg calls in gallery-dl?

return subprocess.Popen(args, stdout=out, stderr=out).wait()

or just -y to the arguments for ffmpeg?

I doubt this has any effect if -nostdin is not enough either, but maybe it helps.

but I do not know what, or even why these signals were sent.

Same. I think this is the first time I have heard about SIGTTOU and SIGTTIN

@thatfuckingbird
Copy link
Contributor Author

Haven't tried the stdin=subprocess.DEVNULL thing but my guess would be that it would have solved the problem on the system where -nostdin was enough, since those two should be roughly equivalent. -y was included in my config the whole time, so that has no effect on the issue.

mikf added a commit that referenced this issue Feb 13, 2022
@mikf
Copy link
Owner

mikf commented Feb 13, 2022

Added a global signals-ignore option that expects a list of signal names that should be ignored.

In a configuration file this options needs to be set at the top level, i.e. the same level as extractor, downloadef, etc.

As a command-line option, -o signals-ignore=SIGTTOU,SIGTTIN works.

@thatfuckingbird
Copy link
Contributor Author

Thanks, I think this can be closed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants