Skip to content

Fix two silent failures in vc2.sh: output ownership and NVDEC codec gating - #7

Open
paxri01 wants to merge 2 commits into
masterfrom
fix/nvdec_codec_gating
Open

paxri01 wants to merge 2 commits into
masterfrom
fix/nvdec_codec_gating

Conversation

@paxri01

@paxri01 paxri01 commented Sep 20, 2026

Copy link
Copy Markdown
Owner

Two bugs found in one vc2 -m run on 2026-09-19. Both failed silently because their errors were being sent to /dev/null or suppressed by -loglevel quiet.

1. Output ownership was never applied

chown $user:$group on the output file and directory has been failing on every run. Changing a file's owner to another user requires root; the script runs as an ordinary user. sudo would not help either — the output shares are exported root_squash, so root has less access there than we do.

With stderr discarded and no return code checked, this was invisible: the chmod on the next line still succeeded, so the files looked as though the ownership block had run. Recent output is rp01:rp01; files from older runs are serviio:video.

Set only the group, which an ordinary member of it is allowed to do. Serviio reads through the shared video group, so rp01:video 0664 grants exactly what serviio:video 0664 did. Output directories also get the setgid bit so season subdirectories inherit the group. Failures are now logged.

2. -hwaccel cuda was applied to codecs the GPU cannot decode

-hwaccel cuda was set once at startup and used for every file. It is a decoder selection directive, not a hint: it replaces the software decoder with the native hwaccel shim, which has no software path. Given a codec NVDEC cannot decode there is no fallback — ffmpeg fails every packet in a loop and never stops.

An AV1 source hit this. The GPU is Turing, which has no AV1 decode block:

[vist#0:0/av1] Selecting decoder 'av1' because of requested hwaccel method cuda
[av1] format supported: no, max_mb_count: 0
[av1] Hardware is lacking required capabilities
[av1] Your platform doesn't support hardware accelerated AV1 decoding.
[dec:av1] Error submitting packet to decoder: Function not implemented

That block repeated 3673 times in 45 seconds, at ~180% CPU with no video written. It looked like a hang, and it was not: audio and subtitles kept encoding and were eventually muxed on their own. The abandoned temp file was 97 MB of audio and subtitles with no video stream, 4996s into a 5106s runtime. Left alone the run would very likely have exited 0, published that over the real film and moved the 1.7 GB source to done/.

Gate the flag on the probed $vCodec instead. AV1 joins the list only when the GPU reports compute capability >= 8.6, where NVDEC gained an AV1 decoder. ffmpeg -hwaccels cannot answer this — it reports that the method exists, never which codecs the silicon handles.

Also drops -loglevel from quiet to error. Quiet is what turned an ffmpeg failing loudly into seven minutes of silence; -stats still provides the progress line.

Verification

  • bash -n and shellcheck -S warning clean.
  • chgrp video + chmod confirmed to succeed as an ordinary user on both the plex and QNAP exports.
  • The AV1 file decodes through libdav1d at 11.9x realtime and encodes on NVENC normally — all three streams present in the output. Full vc2 -m re-run prints NVDEC has no av1 decoder; decoding in software and proceeds.

🤖 Generated with Claude Code

paxri01 and others added 2 commits September 19, 2026 20:03
The chown to serviio:video never took effect. Changing a file's owner to
another user needs root, the script runs as an ordinary user, and both
output shares are exported root_squash, so running it under sudo would
not help either -- root has less access there than we do. With the errors
sent to /dev/null and no return code checked, the failure was invisible:
the chmod on the following line still succeeded, so the files looked as
though the ownership block had run.

Set only the group, which an ordinary member of it is allowed to do.
Serviio reads through the shared video group, so rp01:video 0664 grants
it exactly what serviio:video 0664 did. Output directories also get the
setgid bit so season subdirectories created later inherit the group.

Failures are now logged rather than discarded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
-hwaccel cuda was set once at startup and applied to every file. It is a
decoder selection directive rather than a hint: it replaces the software
decoder with the native hwaccel shim, which has no software path. Given a
codec NVDEC cannot decode there is no fallback -- ffmpeg fails every
packet in a loop and never stops.

An AV1 source hit this today. The GPU is Turing, which has no AV1 decode
block at all, so ffmpeg logged "Your platform doesn't support hardware
accelerated AV1 decoding" and then "Error submitting packet to decoder:
Function not implemented" once per packet, 3673 times in 45 seconds. It
looked like a hang, and it was not: audio and subtitles kept encoding and
were eventually muxed on their own. Left alone it would have written a
video-less 97MB mp4, very likely exited 0, published that over the real
film and moved the 1.7GB source to done/.

Gate the flag on the probed codec instead. AV1 is added to the list only
when the GPU reports compute capability 8.6 or higher, which is where
NVDEC gained an AV1 decoder. -hwaccels cannot answer this: it reports
that the method exists, never which codecs the silicon handles.

The same file decodes through libdav1d at 11.9x realtime and encodes on
NVENC normally, so nothing is lost beyond the decode speed.

Also drop -loglevel from quiet to error. Quiet is what turned an ffmpeg
failing loudly into seven minutes of silence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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

Successfully merging this pull request may close these issues.

1 participant