add nvenc pipeline.

This commit is contained in:
Miroslav Šedivý 2023-03-31 22:17:46 +02:00
parent bdff0841ec
commit 70325e0277
3 changed files with 36 additions and 12 deletions

View File

@ -84,8 +84,9 @@ nat1to1: <ip>
- The resulting stream frames per seconds should be capped *(0 for uncapped)*.
- e.g. `0`
#### `NEKO_HWENC`:
- Use hardware accelerated encoding, for now supported only `VAAPI`.
- e.g. `VAAPI`
- none *(default CPU encoding)*
- vaapi
- nvenc
### Audio

View File

@ -5,6 +5,7 @@ import (
"strings"
"m1k1o/neko/internal/capture/gst"
"m1k1o/neko/internal/config"
"m1k1o/neko/internal/types/codec"
)
@ -52,7 +53,7 @@ func NewBroadcastPipeline(device string, display string, pipelineSrc string, url
return pipelineStr, nil
}
func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc string, fps int16, bitrate uint, hwenc string) (string, error) {
func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc string, fps int16, bitrate uint, hwenc config.HwEnc) (string, error) {
pipelineStr := " ! appsink name=appsinkvideo"
// if using custom pipeline
@ -68,7 +69,7 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
switch rtpCodec.Name {
case codec.VP8().Name:
if hwenc == "VAAPI" {
if hwenc == config.HwEncVAAPI {
if err := gst.CheckPlugins([]string{"ximagesrc", "vaapi"}); err != nil {
return "", err
}
@ -138,13 +139,18 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
return "", err
}
if hwenc == "VAAPI" {
if hwenc == config.HwEncVAAPI {
if err := gst.CheckPlugins([]string{"vaapi"}); err != nil {
return "", err
}
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! vaapih264enc rate-control=vbr bitrate=%d keyframe-period=180 quality-level=7 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate)
} else if hwenc == config.HwEncNVENC {
if err := gst.CheckPlugins([]string{"nvcodec"}); err != nil {
return "", err
}
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! nvh264enc name=encoder preset=5 zerolatency=1 gop-size=15 bitrate=%d rc-mode=5 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate)
} else {
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
// gstreamer1.0-plugins-bad

View File

@ -2,6 +2,7 @@ package config
import (
"m1k1o/neko/internal/types/codec"
"strings"
"github.com/pion/webrtc/v3"
"github.com/rs/zerolog/log"
@ -9,13 +10,21 @@ import (
"github.com/spf13/viper"
)
type HwEnc int
const (
HwEncNone HwEnc = iota
HwEncVAAPI
HwEncNVENC
)
type Capture struct {
// video
Display string
VideoCodec codec.RTPCodec
VideoHWEnc string // TODO: Pipeline builder.
VideoBitrate uint // TODO: Pipeline builder.
VideoMaxFPS int16 // TODO: Pipeline builder.
VideoHWEnc HwEnc // TODO: Pipeline builder.
VideoBitrate uint // TODO: Pipeline builder.
VideoMaxFPS int16 // TODO: Pipeline builder.
VideoPipeline string
// audio
@ -184,11 +193,19 @@ func (s *Capture) Set() {
log.Warn().Msg("you are using deprecated config setting 'NEKO_AV1=true', use 'NEKO_VIDEO_CODEC=av1' instead")
}
videoHWEnc := ""
if viper.GetString("hwenc") == "VAAPI" {
videoHWEnc = "VAAPI"
videoHWEnc := strings.ToLower(viper.GetString("hwenc"))
switch videoHWEnc {
case "":
fallthrough
case "none":
s.VideoHWEnc = HwEncNone
case "vaapi":
s.VideoHWEnc = HwEncVAAPI
case "nvenc":
s.VideoHWEnc = HwEncNVENC
default:
log.Warn().Str("hwenc", videoHWEnc).Msgf("unknown video hw encoder, using CPU")
}
s.VideoHWEnc = videoHWEnc
s.VideoBitrate = viper.GetUint("video_bitrate")
s.VideoMaxFPS = int16(viper.GetInt("max_fps"))