diff --git a/hlsvod/transcode.go b/hlsvod/transcode.go index 1b04b00..12eb935 100644 --- a/hlsvod/transcode.go +++ b/hlsvod/transcode.go @@ -6,5 +6,6 @@ import ( "fmt" "log" + "os" "os/exec" "path" "strings" @@ -56,6 +57,16 @@ func TranscodeSegments(ctx context.Context, ffmpegBinary string, config Transcod }...) } + // Decode and filter on the GPU when a VAAPI render device is configured. + // This is opt-in so upstream's software behavior remains available. + vaapiDevice := os.Getenv("TRANSCODE_VAAPI_DEVICE") + if vaapiDevice != "" { + args = append(args, []string{ + "-init_hw_device", "vaapi=va:" + vaapiDevice, + "-filter_hw_device", "va", "-hwaccel", "vaapi", "-hwaccel_output_format", "vaapi", + }...) + } + // Input specs args = append(args, []string{ "-i", config.InputFilePath, // Input file @@ -79,17 +89,26 @@ func TranscodeSegments(ctx context.Context, ffmpegBinary string, config Transcod if profile.Width >= profile.Height { scale = fmt.Sprintf("scale=-2:%d", profile.Height) } else { scale = fmt.Sprintf("scale=%d:-2", profile.Width) } - args = append(args, []string{ - "-vf", scale, - "-c:v", "libx264", - "-preset", "faster", - "-profile:v", "high", - "-level:v", "4.0", - "-b:v", fmt.Sprintf("%dk", profile.Bitrate), - }...) + if vaapiDevice != "" { + if profile.Width >= profile.Height { + scale = fmt.Sprintf("scale_vaapi=w=-2:h=%d:format=nv12", profile.Height) + } else { + scale = fmt.Sprintf("scale_vaapi=w=%d:h=-2:format=nv12", profile.Width) + } + args = append(args, []string{ + "-vf", scale, "-c:v", "h264_vaapi", "-profile:v", "high", + "-level:v", "4.0", "-b:v", fmt.Sprintf("%dk", profile.Bitrate), + }...) + } else { + args = append(args, []string{ + "-vf", scale, "-c:v", "libx264", "-preset", "faster", + "-profile:v", "high", "-level:v", "4.0", + "-b:v", fmt.Sprintf("%dk", profile.Bitrate), + }...) + } } // Audio specs