Documentation
¶
Overview ¶
Package nvidia checks, before any long job, that an ffmpeg binary and the machine can do the NVIDIA GPU work a run asks for: NVDEC decoding (decode.WithHWAccel), and NVENC encoding (ladder.Options.Encoder set to encode.HardwareNVENC).
The two fail differently, which is why this package exists: a hardware decode that fails falls back to the CPU on its own, while an NVENC ladder has no fallback and fails at its first probe encode, possibly after the analysis and VMAF stages of a run. Check turns both into an error in a second, with the reason (ffmpeg built without NVIDIA support, no usable device, an encoder this GPU lacks) and how to fix it.
CUDA VMAF is checked by libvmaf itself: see libvmaf.InitCUDA in package vmaf/libvmaf. This package needs no cgo.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMissing is returned when ffmpeg was built without a component. ErrMissing = errors.New("ffmpeg lacks NVIDIA support") // ErrDevice is returned when the CUDA device cannot be opened. ErrDevice = errors.New("no usable NVIDIA GPU") // ErrEncoder is returned when an NVENC encoder fails on this GPU. ErrEncoder = errors.New("NVENC encoder unusable") )
Functions ¶
func Available ¶
Available reports whether the ffmpeg binary decodes with NVDEC, has NVENC (H.264) and opens the CUDA device: whether offering the GPU makes sense. It encodes nothing, so it is cheaper than Check, which a run should still call with its actual requirements.
func Check ¶
func Check( ctx context.Context, ffmpeg string, req Requirements, ) error
Check verifies that the ffmpeg binary and this machine can do the GPU work of req, in a few short ffmpeg runs: ffmpeg was built with NVDEC (and the GPU scaler) and the NVENC encoders, the CUDA device opens, and each NVENC encoder encodes a frame at the bit depth (AV1 needs an Ada Lovelace GPU or newer, 10-bit H.264 a Blackwell, and every encoder a free NVENC session). A failed check is a *CheckError; failing to run ffmpeg at all is returned as is.
Example ¶
Check what a GPU run needs before starting it: NVDEC decoding, and Main10 AV1 and HEVC ladders on NVENC. NVDEC would fall back to the CPU by itself, NVENC would fail at the first probe encode.
package main
import (
"context"
"errors"
"fmt"
"github.com/eko/qc/decode"
"github.com/eko/qc/nvidia"
)
func main() {
err := nvidia.Check(context.Background(), "ffmpeg", nvidia.Requirements{
HWAccel: decode.HWAccelCUDA,
Codecs: []string{"av1", "hevc"},
BitDepth: 10,
})
var checkErr *nvidia.CheckError
switch {
case err == nil:
fmt.Println("GPU ready")
case errors.As(err, &checkErr) && checkErr.Part == nvidia.PartEncoding:
fmt.Println("build the ladders on the CPU:", checkErr.Err)
default:
fmt.Println("stay on the CPU:", err)
}
}
Output:
Types ¶
type Capabilities ¶
Capabilities are the components an ffmpeg binary was built with: its hardware decoding methods, encoders and filters. Being built in does not mean usable: the GPU, its driver and its generation decide (see Check).
func Probe ¶
func Probe( ctx context.Context, ffmpeg string, ) (Capabilities, error)
Probe lists the hardware decoding methods, encoders and filters of the ffmpeg binary.
func (Capabilities) RequireDecoding ¶
func (c Capabilities) RequireDecoding( mode decode.HWAccel, ) error
RequireDecoding checks that ffmpeg can decode in mode: NVDEC for decode.HWAccelCUDA, plus the GPU scaler for decode.HWAccelCUDAScale. Other modes (none, VideoToolbox) require nothing from the GPU.
func (Capabilities) RequireEncoders ¶
func (c Capabilities) RequireEncoders( encoders []string, ) error
RequireEncoders checks that ffmpeg has every encoder (h264_nvenc...).
type CheckError ¶
CheckError is a failed check: the part of the GPU work that cannot run, and why (wrapping ErrMissing, ErrDevice or ErrEncoder). A caller can use the part to fall back, e.g. to the CPU encoders when only NVENC fails.
func (*CheckError) Unwrap ¶
func (e *CheckError) Unwrap() error
Unwrap returns the reason of the failure.
type Part ¶
type Part string
Part is the part of the GPU work a failed check concerns.
const ( // PartDecoding is NVDEC decoding and GPU scaling (Requirements.HWAccel). PartDecoding Part = "decoding" // PartEncoding is NVENC encoding (Requirements.Codecs). PartEncoding Part = "encoding" // PartDevice is the CUDA device every part needs. PartDevice Part = "device" )
Parts of the GPU work.
type Requirements ¶
type Requirements struct {
// HWAccel is the hardware decoding mode (decode.WithHWAccel).
HWAccel decode.HWAccel
// Codecs are the codecs encoded with NVENC (h264, hevc, av1): the
// codecs of the ladders built with encode.HardwareNVENC.
Codecs []string
// BitDepth is the bit depth of the NVENC encodes: 8 (the default) or
// 10, which older GPUs lack for some codecs.
BitDepth int
}
Requirements are the GPU work a run asks for. The zero value asks for nothing, and Check then runs nothing.