add nvenc pipeline.
This commit is contained in:
parent
bdff0841ec
commit
70325e0277
@ -84,8 +84,9 @@ nat1to1: <ip>
|
|||||||
- The resulting stream frames per seconds should be capped *(0 for uncapped)*.
|
- The resulting stream frames per seconds should be capped *(0 for uncapped)*.
|
||||||
- e.g. `0`
|
- e.g. `0`
|
||||||
#### `NEKO_HWENC`:
|
#### `NEKO_HWENC`:
|
||||||
- Use hardware accelerated encoding, for now supported only `VAAPI`.
|
- none *(default CPU encoding)*
|
||||||
- e.g. `VAAPI`
|
- vaapi
|
||||||
|
- nvenc
|
||||||
|
|
||||||
### Audio
|
### Audio
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"m1k1o/neko/internal/capture/gst"
|
"m1k1o/neko/internal/capture/gst"
|
||||||
|
"m1k1o/neko/internal/config"
|
||||||
"m1k1o/neko/internal/types/codec"
|
"m1k1o/neko/internal/types/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ func NewBroadcastPipeline(device string, display string, pipelineSrc string, url
|
|||||||
return pipelineStr, nil
|
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"
|
pipelineStr := " ! appsink name=appsinkvideo"
|
||||||
|
|
||||||
// if using custom pipeline
|
// if using custom pipeline
|
||||||
@ -68,7 +69,7 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
|
|||||||
|
|
||||||
switch rtpCodec.Name {
|
switch rtpCodec.Name {
|
||||||
case codec.VP8().Name:
|
case codec.VP8().Name:
|
||||||
if hwenc == "VAAPI" {
|
if hwenc == config.HwEncVAAPI {
|
||||||
if err := gst.CheckPlugins([]string{"ximagesrc", "vaapi"}); err != nil {
|
if err := gst.CheckPlugins([]string{"ximagesrc", "vaapi"}); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -138,13 +139,18 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if hwenc == "VAAPI" {
|
if hwenc == config.HwEncVAAPI {
|
||||||
if err := gst.CheckPlugins([]string{"vaapi"}); err != nil {
|
if err := gst.CheckPlugins([]string{"vaapi"}); err != nil {
|
||||||
return "", err
|
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)
|
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 {
|
} else {
|
||||||
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
|
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
|
||||||
// gstreamer1.0-plugins-bad
|
// gstreamer1.0-plugins-bad
|
||||||
|
@ -2,6 +2,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"m1k1o/neko/internal/types/codec"
|
"m1k1o/neko/internal/types/codec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pion/webrtc/v3"
|
"github.com/pion/webrtc/v3"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@ -9,13 +10,21 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type HwEnc int
|
||||||
|
|
||||||
|
const (
|
||||||
|
HwEncNone HwEnc = iota
|
||||||
|
HwEncVAAPI
|
||||||
|
HwEncNVENC
|
||||||
|
)
|
||||||
|
|
||||||
type Capture struct {
|
type Capture struct {
|
||||||
// video
|
// video
|
||||||
Display string
|
Display string
|
||||||
VideoCodec codec.RTPCodec
|
VideoCodec codec.RTPCodec
|
||||||
VideoHWEnc string // TODO: Pipeline builder.
|
VideoHWEnc HwEnc // TODO: Pipeline builder.
|
||||||
VideoBitrate uint // TODO: Pipeline builder.
|
VideoBitrate uint // TODO: Pipeline builder.
|
||||||
VideoMaxFPS int16 // TODO: Pipeline builder.
|
VideoMaxFPS int16 // TODO: Pipeline builder.
|
||||||
VideoPipeline string
|
VideoPipeline string
|
||||||
|
|
||||||
// audio
|
// 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")
|
log.Warn().Msg("you are using deprecated config setting 'NEKO_AV1=true', use 'NEKO_VIDEO_CODEC=av1' instead")
|
||||||
}
|
}
|
||||||
|
|
||||||
videoHWEnc := ""
|
videoHWEnc := strings.ToLower(viper.GetString("hwenc"))
|
||||||
if viper.GetString("hwenc") == "VAAPI" {
|
switch videoHWEnc {
|
||||||
videoHWEnc = "VAAPI"
|
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.VideoBitrate = viper.GetUint("video_bitrate")
|
||||||
s.VideoMaxFPS = int16(viper.GetInt("max_fps"))
|
s.VideoMaxFPS = int16(viper.GetInt("max_fps"))
|
||||||
|
Reference in New Issue
Block a user