feat(transcode): dynamic H.264 level + HW probe + capability reporting
Three related fixes around 4K-source transcoding that left the web player stuck on "preparing session" with no useful diagnostics: 1. Dynamic -level:v derived from output height (hls.go, transcoder.go). The previous fixed "4.0" silently rejected anything taller than 1080p inside libx264 — "frame MB size > level limit", "DPB size > level limit" — and emitted unplayable segments. Helper H264LevelForHeight() now picks 4.0 / 5.0 / 5.1 / 6.0 from the actual encode height. 2. New `unarr probe-hwaccel` diagnostic command. Lists the HW encoders compiled into ffmpeg, the device files / drivers present, and the backend the daemon would actually pick today. Surfaces the canonical gotcha: a host with an RTX 3090 + nvidia-smi but a Homebrew ffmpeg built without --enable-nvenc still falls back to libx264 software. 3. Register payload now includes hwAccel + maxTranscodeHeight so the web side can suggest a smaller alternate quality before the user even tries to play a 4K source on a software-only host. Software-only = 1080p cap, any HW backend = 2160p cap.
This commit is contained in:
parent
01941ed2e4
commit
209ea38ecf
9 changed files with 297 additions and 30 deletions
|
|
@ -845,9 +845,21 @@ func buildHLSFFmpegArgsAt(cfg HLSSessionConfig, probe *StreamProbe, tmpDir strin
|
|||
case "h264_qsv":
|
||||
args = append(args, "-preset", "medium", "-look_ahead", "0")
|
||||
}
|
||||
args = append(args, "-profile:v", "main", "-level:v", "4.0")
|
||||
|
||||
// Derive H.264 level from the actual output height. A fixed "4.0" caps the
|
||||
// encoder at 1080p — anything taller (1440p, 4K source on quality=original)
|
||||
// fails libx264 with "frame MB size > level limit" and emits unplayable
|
||||
// segments. The output height matches qcap.MaxHeight when the source is
|
||||
// downscaled, otherwise probe.Height (already populated by ffprobe).
|
||||
qcap := resolveQualityCap(cfg.Quality)
|
||||
outputHeight := qcap.MaxHeight
|
||||
if outputHeight == 0 {
|
||||
outputHeight = cfg.Transcode.MaxHeight
|
||||
}
|
||||
if outputHeight == 0 || (probe.Height > 0 && probe.Height < outputHeight) {
|
||||
outputHeight = probe.Height
|
||||
}
|
||||
args = append(args, "-profile:v", "main", "-level:v", H264LevelForHeight(outputHeight))
|
||||
|
||||
bitrate := qcap.VideoBitrate
|
||||
if bitrate == "" {
|
||||
bitrate = cfg.Transcode.VideoBitrate
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue