master-of-zen / Av1an

Cross-platform command-line AV1 / VP9 / HEVC / H264 encoding framework with per scene quality encoding
GNU General Public License v3.0
1.51k stars 155 forks source link

--target-quality does not work consistently on Windows #551

Open woot000 opened 2 years ago

woot000 commented 2 years ago

Using Windows 11 build 22533, Av1an 0.3.1 (the windows binary here) and aomenc 3.2.0-411-gd872c3410

Encoding long videos (higher than 40-50 chunks) with the option '--target-quality XX' often results in a crash that outputs this:

av1an -i test.mp4 -a " -c:a libopus -b:a 64k" -v " --cpu-used=3 --cq-level=35 --end-usage=q --bit-depth=10 --row-mt=0 --tile-columns=0 --tile-rows=0 --frame-parallel=0 --enable-fwd-kf=1 --lag-in-frames=48 --enable-tpl-model=1 --auto-alt-ref=0 --aq-mode=2" --target-quality 93 --vmaf-path vmaf_v0.6.1.json -o test.webm

Queue 177 Workers 8 Passes 2
Params: --cpu-used=3 --cq-level=35 --end-usage=q --bit-depth=10 --row-mt=0 --tile-columns=0 --tile-rows=0 --frame-parallel=0 --enable-fwd-kf=1 --lag-in-frames=48 --enable-tpl-model=1 --auto-alt-ref=0 --aq-mode=2
ERROR [av1an_core::target_quality] [chunk 17] encoder crashed: exit code: 1
stdout:

stderr:
        Fatal: Specify stream dimensions with --width (-w)  and --height (-h)

source pipe stderr:
        pipe:: Invalid data found when processing input

ERROR [av1an_core::broker] [chunk 17] encoder crashed: exit code: 1
stdout:

stderr:
        Fatal: Specify stream dimensions with --width (-w)  and --height (-h)

source pipe stderr:
        pipe:: Invalid data found when processing input

Sometimes, this crash doesn't happen, but instead Av1an stalls after encoding the first set of chunks:

av1an -i test.mp4 -a " -c:a libopus -b:a 64k" -v " --cpu-used=3 --cq-level=35 --end-usage=q --bit-depth=10 --row-mt=0 --tile-columns=0 --tile-rows=0 --frame-parallel=0 --enable-fwd-kf=1 --lag-in-frames=48 --enable-tpl-model=1 --auto-alt-ref=0 --aq-mode=2" --target-quality 93 --vmaf-path vmaf_v0.6.1.json -o test.webm

Scene detection
00:05:06 [##############################################################################################] 100%  41939/41939 (136.77 fps, eta 0s) Queue 177 Workers 7 Passes 2
Params: --cpu-used=3 --cq-level=35 --end-usage=q --bit-depth=10 --row-mt=0 --tile-columns=0 --tile-rows=0 --frame-parallel=0 --enable-fwd-kf=1 --lag-in-frames=48 --enable-tpl-model=1 --auto-alt-ref=0 --aq-mode=2
00:02:36 [-------------------------------------------------------------------------------------------------------]   0%  0/41939 (0 fps, eta 0s) 

1 2

Short videos do work with aom + --target-quality XX (1 chunk always worked for me, 2-20 chunks would work sometimes).

Encoding without using --target-quality XX works as expected, and encoding using --target-quality XX + -e x264/x265 works as expected.

woot000 commented 2 years ago

After installing LSMASH and ffms2 and using either of them as the chunking method (av1an -i longvideo.mp4 -m lsmash --target-quality 93), only the latter error occurs where there are stalled ffmpeg/vspipe executables.

I can get av1an to continue encoding the video by killing the stalled ffmpeg pipes, but then they come back after a short while, and it always stalls whenever aomenc is being used to probe for VMAF quality (I think it stalls after it pipes the last frame? Not certain about this). Progress is made during this time, but not much

Not sure if the following information will be particularly useful, but the ffmpeg executable I use is of a more recent version than the dynamic libraries that av1an needs in order to run

ffmpeg version N-105350-g720cf0d9a5-g0a83ecbf48+1 Copyright (c) 2000-2022 the FFmpeg developers
built with clang version 13.0.0
lavalamp3774 commented 2 years ago

I am having the same problem on Windows 10 with --target-quality causing hanging, and have tried Av1an versions 0.3.1, 0.3.0 and 0.2.0 as well as several combinations of FFMPEG and associated DLL's.

I can say that the initial error of woot is from using a too new nightly FFMPEG build, and version 5.0.0 causes the same error, so that is unrelated to the hanging issue.

Any time I put --target-quality in, it stalls out. An example command that fails for me:

av1an -i "in.mp4" -v " --cpu-used=3 --end-usage=q --cq-level=20 --enable-dnl-denoising=0 --denoise-noise-level=10 --threads=8" --target-quality 96 -a " -an" --vmaf --vmaf-path "vmaf_float_v0.6.1.json" -s scenes.json -l log.txt -o "out.mp4"

If I leave out the --target-quality flag, then it encodes just fine, and even produces the final VMAF analysis SVG file, but of course that is encoded at constant CRF.

woot000 commented 2 years ago

just tested it again with av1an compiled to the latest commit, this bug still occurs as I described it back in january, albeit without the "Specify stream dimensions " message coming up at all

i've found out after doing some testing that pipes don't stall if I set the maximum scene length to a fairly small number of frames. on a 1080p 59.97fps AVC video I downloaded from YT, the stalling seems to occur when I use this command:

av1an -i a.mp4 --target-quality 85 --split-method none -m lsmash --max-tries 100 -w 3 -x 217
INFO [av1an_core::settings] scenecut: found 1 scene(s) [with extra_splits (217 frames): 448 scene(s)]

but not when i use this command:

av1an -i a.mp4 --target-quality 85 --split-method none -m lsmash --max-tries 100 -w 3 -x 216
INFO [av1an_core::settings] scenecut: found 1 scene(s) [with extra_splits (216 frames): 450 scene(s)]

a similar thing happened when I tested a 4K 23.98fps AVC video I had, but with different maximum scene length numbers this stalls:

av1an -i b.mp4 --target-quality 85 --split-method none -m lsmash --max-tries 100 -w 3 -x 226
INFO [av1an_core::settings] scenecut: found 1 scene(s) [with extra_splits (226 frames): 10 scene(s)]

this works:

av1an -i b.mp4 --target-quality 85 --split-method none -m lsmash --max-tries 100 -w 3 -x 225
INFO [av1an_core::settings] scenecut: found 1 scene(s) [with extra_splits (225 frames): 11 scene(s)]

setting the max scene length to a low frame count appears to be a workaround for getting a VMAF encode working on Windows without getting zombie pipes, but it's a pretty annoying workaround if I'm trying to compress a video to a small size

FreezyLemon commented 2 years ago

Rust has changed the default pipe buffer size from 4kb to 64kb: rust-lang/rust/pull/95782. Maybe try compiling with a cargo/rustc version >=1.62.0 and try again.

The actual problem isn't solved (some stderr pipes just get filled up while the command runs, filling up the buffer), but if the buffer is always big enough, the issue is essentially solved.

Edit: The latest nightly build was completed on Rust 1.62.0 as far as I can tell. Try that one and see if it works.