Kyoo/transcoder/src/hwaccel.go
2024-02-26 14:32:25 +01:00

87 lines
2.8 KiB
Go

package src
import (
"log"
"os"
)
func DetectHardwareAccel() HwAccelT {
name := GetEnvOr("GOTRANSCODER_HWACCEL", "disabled")
log.Printf("Using hardware acceleration: %s", name)
switch name {
case "disabled":
return HwAccelT{
Name: "disabled",
DecodeFlags: []string{},
EncodeFlags: []string{
"-c:v", "libx264",
// superfast or ultrafast would produce a file extremly big so we prever veryfast or faster.
"-preset", "fast",
// sc_threshold is a scene detection mechanisum used to create a keyframe when the scene changes
// this is on by default and inserts keyframes where we don't want to (it also breaks force_key_frames)
// we disable it to prevents whole scenes from behing removed due to the -f segment failing to find the corresonding keyframe
"-sc_threshold", "0",
},
// we could put :force_original_aspect_ratio=decrease:force_divisible_by=2 here but we already calculate a correct width and
// aspect ratio in our code so there is no need.
ScaleFilter: "scale=%d:%d",
}
case "nvidia":
return HwAccelT{
Name: "nvidia",
DecodeFlags: []string{
"-hwaccel", "cuda",
// this flag prevents data to go from gpu space to cpu space
// it forces the whole dec/enc to be on the gpu. We want that.
"-hwaccel_output_format", "cuda",
},
EncodeFlags: []string{
"-c:v", "h264_nvenc",
"-preset", "fast",
// the exivalent of -sc_threshold on nvidia.
"-no-scenecut", "1",
},
// if the decode goes into system memory, we need to prepend the filters with "hwupload_cuda".
// since we use hwaccel_output_format, decoded data stays in gpu memory so we must not specify it (it errors)
ScaleFilter: "scale_cuda=%d:%d",
}
case "vaapi":
return HwAccelT{
Name: name,
DecodeFlags: []string{
"-hwaccel", "vaapi",
"-hwaccel_device", GetEnvOr("GOTRANSCODER_VAAPI_RENDERER", "/dev/dri/renderD128"),
"-hwaccel_output_format", "vaapi",
},
EncodeFlags: []string{
// h264_vaapi does not have any preset or scenecut flags.
"-c:v", "h264_vaapi",
// if the hardware decoder could not work and fallbacked to soft decode, we need to instruct ffmpeg to
// upload back frames to gpu space (after converting them)
// see https://trac.ffmpeg.org/wiki/Hardware/VAAPI#Encoding for more info
// "-vf", "format=nv12|vaapi,hwupload",
},
ScaleFilter: "scale_vaapi=%d:%d",
}
case "qsv", "intel":
return HwAccelT{
Name: name,
DecodeFlags: []string{
"-hwaccel", "qsv",
// "-qsv_device", GetEnvOr("GOTRANSCODER_QSV_RENDERER", "/dev/dri/renderD128"),
"-hwaccel_output_format", "qsv",
},
EncodeFlags: []string{
"-c:v", "h264_qsv",
"-preset", "fast",
},
ScaleFilter: "scale_qsv=%d:%d",
}
default:
log.Printf("No hardware accelerator named: %s", name)
os.Exit(2)
panic("unreachable")
}
}