From d880e4384f5821c0e2b77e7c6971f68102010923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Tue, 2 Feb 2021 16:58:17 +0100 Subject: [PATCH] RTPCodec as functions. --- internal/capture/gst/gst.go | 16 +-- internal/capture/manager.go | 4 +- internal/config/capture.go | 26 ++--- internal/types/capture.go | 4 +- internal/types/codec/codecs.go | 207 +++++++++++++++++---------------- internal/webrtc/manager.go | 4 +- 6 files changed, 136 insertions(+), 125 deletions(-) diff --git a/internal/capture/gst/gst.go b/internal/capture/gst/gst.go index 9527c257..135f5443 100644 --- a/internal/capture/gst/gst.go +++ b/internal/capture/gst/gst.go @@ -67,11 +67,11 @@ func CreateJPEGPipeline(pipelineDisplay string, pipelineSrc string, rate string, } // CreateAppPipeline creates a GStreamer Pipeline -func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc string) (*Pipeline, error) { +func CreateAppPipeline(codecRTP codec.RTPCodec, pipelineDevice string, pipelineSrc string) (*Pipeline, error) { var pipelineStr string switch codecRTP.Name { - case codec.VP8: + case "vp8": // https://gstreamer.freedesktop.org/documentation/vpx/vp8enc.html?gi-language=c // gstreamer1.0-plugins-good // vp8enc error-resilient=partitions keyframe-max-dist=10 auto-alt-ref=true cpu-used=5 deadline=1 @@ -80,7 +80,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } pipelineStr = fmt.Sprintf(videoSrc + "vp8enc cpu-used=8 threads=2 deadline=1 error-resilient=partitions keyframe-max-dist=10 auto-alt-ref=true" + appSink, pipelineDevice) - case codec.VP9: + case "vp9": // https://gstreamer.freedesktop.org/documentation/vpx/vp9enc.html?gi-language=c // gstreamer1.0-plugins-good // vp9enc @@ -89,7 +89,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } pipelineStr = fmt.Sprintf(videoSrc + "vp9enc" + appSink, pipelineDevice) - case codec.H264: + case "h264": if err := CheckPlugins([]string{"ximagesrc"}); err != nil { return nil, err } @@ -112,7 +112,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } return nil, err - case codec.Opus: + case "opus": // https://gstreamer.freedesktop.org/documentation/opus/opusenc.html // gstreamer1.0-plugins-base // opusenc @@ -121,7 +121,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } pipelineStr = fmt.Sprintf(audioSrc + "opusenc" + appSink, pipelineDevice) - case codec.G722: + case "g722": // https://gstreamer.freedesktop.org/documentation/libav/avenc_g722.html?gi-language=c // gstreamer1.0-libav // avenc_g722 @@ -130,7 +130,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } pipelineStr = fmt.Sprintf(audioSrc + "avenc_g722" + appSink, pipelineDevice) - case codec.PCMU: + case "pcmu": // https://gstreamer.freedesktop.org/documentation/mulaw/mulawenc.html?gi-language=c // gstreamer1.0-plugins-good // audio/x-raw, rate=8000 ! mulawenc @@ -139,7 +139,7 @@ func CreateAppPipeline(codecRTP codec.RTP, pipelineDevice string, pipelineSrc st } pipelineStr = fmt.Sprintf(audioSrc + "audio/x-raw, rate=8000 ! mulawenc" + appSink, pipelineDevice) - case codec.PCMA: + case "pcma": // https://gstreamer.freedesktop.org/documentation/alaw/alawenc.html?gi-language=c // gstreamer1.0-plugins-good // audio/x-raw, rate=8000 ! alawenc diff --git a/internal/capture/manager.go b/internal/capture/manager.go index 2116b394..e217119f 100644 --- a/internal/capture/manager.go +++ b/internal/capture/manager.go @@ -126,11 +126,11 @@ func (manager *CaptureManagerCtx) Screencast() types.ScreencastManager { return manager.screencast } -func (manager *CaptureManagerCtx) VideoCodec() codec.RTP { +func (manager *CaptureManagerCtx) VideoCodec() codec.RTPCodec { return manager.config.VideoCodec } -func (manager *CaptureManagerCtx) AudioCodec() codec.RTP { +func (manager *CaptureManagerCtx) AudioCodec() codec.RTPCodec { return manager.config.AudioCodec } diff --git a/internal/config/capture.go b/internal/config/capture.go index fb072d02..5c1334b0 100644 --- a/internal/config/capture.go +++ b/internal/config/capture.go @@ -10,9 +10,9 @@ import ( type Capture struct { Display string Device string - AudioCodec codec.RTP + AudioCodec codec.RTPCodec AudioParams string - VideoCodec codec.RTP + VideoCodec codec.RTPCodec VideoParams string BroadcastPipeline string @@ -111,30 +111,30 @@ func (Capture) Init(cmd *cobra.Command) error { } func (s *Capture) Set() { - var videoCodec codec.RTP + var videoCodec codec.RTPCodec if viper.GetBool("vp8") { - videoCodec = codec.New(codec.VP8) + videoCodec = codec.VP8() } else if viper.GetBool("vp9") { - videoCodec = codec.New(codec.VP9) + videoCodec = codec.VP9() } else if viper.GetBool("h264") { - videoCodec = codec.New(codec.H264) + videoCodec = codec.H264() } else { // default - videoCodec = codec.New(codec.VP8) + videoCodec = codec.VP8() } - var audioCodec codec.RTP + var audioCodec codec.RTPCodec if viper.GetBool("opus") { - audioCodec = codec.New(codec.Opus) + audioCodec = codec.Opus() } else if viper.GetBool("g722") { - audioCodec = codec.New(codec.G722) + audioCodec = codec.G722() } else if viper.GetBool("pcmu") { - audioCodec = codec.New(codec.PCMU) + audioCodec = codec.PCMU() } else if viper.GetBool("pcma") { - audioCodec = codec.New(codec.PCMA) + audioCodec = codec.PCMA() } else { // default - audioCodec = codec.New(codec.Opus) + audioCodec = codec.Opus() } s.Device = viper.GetString("device") diff --git a/internal/types/capture.go b/internal/types/capture.go index 7af5d01f..030a8ea9 100644 --- a/internal/types/capture.go +++ b/internal/types/capture.go @@ -28,8 +28,8 @@ type CaptureManager interface { Broadcast() BroadcastManager Screencast() ScreencastManager - VideoCodec() codec.RTP - AudioCodec() codec.RTP + VideoCodec() codec.RTPCodec + AudioCodec() codec.RTPCodec OnVideoFrame(listener func(sample Sample)) OnAudioFrame(listener func(sample Sample)) diff --git a/internal/types/codec/codecs.go b/internal/types/codec/codecs.go index 4ffc4db7..e902dd10 100644 --- a/internal/types/codec/codecs.go +++ b/internal/types/codec/codecs.go @@ -2,112 +2,123 @@ package codec import "github.com/pion/webrtc/v3" -const ( - VP8 = "vp8" - VP9 = "vp9" - H264 = "h264" - Opus = "opus" - G722 = "g722" - PCMU = "pcmu" - PCMA = "pcma" -) - -type RTP struct { +type RTPCodec struct { Name string PayloadType webrtc.PayloadType Type webrtc.RTPCodecType Capability webrtc.RTPCodecCapability } -func New(codecType string) RTP { - codec := RTP{} - - switch codecType { - case "vp8": - codec.Name = "vp8" - codec.PayloadType = 96 - codec.Type = webrtc.RTPCodecTypeVideo - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeVP8, - ClockRate: 90000, - Channels: 0, - SDPFmtpLine: "", - RTCPFeedback: nil, - } - case "vp9": - codec.Name = "vp9" - codec.PayloadType = 98 - codec.Type = webrtc.RTPCodecTypeVideo - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeVP9, - ClockRate: 90000, - Channels: 0, - SDPFmtpLine: "profile-id=0", - RTCPFeedback: nil, - } - case "h264": - codec.Name = "h264" - codec.PayloadType = 102 - codec.Type = webrtc.RTPCodecTypeVideo - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeH264, - ClockRate: 90000, - Channels: 0, - SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", - RTCPFeedback: nil, - } - case "opus": - codec.Name = "opus" - codec.PayloadType = 111 - codec.Type = webrtc.RTPCodecTypeAudio - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeOpus, - ClockRate: 48000, - Channels: 2, - SDPFmtpLine: "", - RTCPFeedback: nil, - } - case "g722": - codec.Name = "g722" - codec.PayloadType = 9 - codec.Type = webrtc.RTPCodecTypeAudio - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypeG722, - ClockRate: 8000, - Channels: 0, - SDPFmtpLine: "", - RTCPFeedback: nil, - } - case "pcmu": - codec.Name = "pcmu" - codec.PayloadType = 0 - codec.Type = webrtc.RTPCodecTypeAudio - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypePCMU, - ClockRate: 8000, - Channels: 0, - SDPFmtpLine: "", - RTCPFeedback: nil, - } - case "pcma": - codec.Name = "pcma" - codec.PayloadType = 8 - codec.Type = webrtc.RTPCodecTypeAudio - codec.Capability = webrtc.RTPCodecCapability{ - MimeType: webrtc.MimeTypePCMA, - ClockRate: 8000, - Channels: 0, - SDPFmtpLine: "", - RTCPFeedback: nil, - } - } - - return codec -} - -func (codec *RTP) Register(engine *webrtc.MediaEngine) error { +func (codec *RTPCodec) Register(engine *webrtc.MediaEngine) error { return engine.RegisterCodec(webrtc.RTPCodecParameters{ RTPCodecCapability: codec.Capability, PayloadType: codec.PayloadType, }, codec.Type) } + +func VP8() RTPCodec { + return RTPCodec{ + Name: "vp8", + PayloadType: 96, + Type: webrtc.RTPCodecTypeVideo, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeVP8, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + } +} + +// TODO: Profile ID. +func VP9() RTPCodec { + return RTPCodec{ + Name: "vp9", + PayloadType: 98, + Type: webrtc.RTPCodecTypeVideo, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeVP9, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "profile-id=0", + RTCPFeedback: nil, + }, + } +} + +// TODO: Profile ID. +func H264() RTPCodec { + return RTPCodec{ + Name: "h264", + PayloadType: 102, + Type: webrtc.RTPCodecTypeVideo, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeH264, + ClockRate: 90000, + Channels: 0, + SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", + RTCPFeedback: nil, + }, + } +} + +func Opus() RTPCodec { + return RTPCodec{ + Name: "opus", + PayloadType: 111, + Type: webrtc.RTPCodecTypeAudio, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeOpus, + ClockRate: 48000, + Channels: 2, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + } +} + +func G722() RTPCodec { + return RTPCodec{ + Name: "g722", + PayloadType: 9, + Type: webrtc.RTPCodecTypeAudio, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypeG722, + ClockRate: 8000, + Channels: 0, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + } +} + +func PCMU() RTPCodec { + return RTPCodec{ + Name: "pcmu", + PayloadType: 0, + Type: webrtc.RTPCodecTypeAudio, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypePCMU, + ClockRate: 8000, + Channels: 0, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + } +} + +func PCMA() RTPCodec { + return RTPCodec{ + Name: "pcma", + PayloadType: 8, + Type: webrtc.RTPCodecTypeAudio, + Capability: webrtc.RTPCodecCapability{ + MimeType: webrtc.MimeTypePCMA, + ClockRate: 8000, + Channels: 0, + SDPFmtpLine: "", + RTCPFeedback: nil, + }, + } +} diff --git a/internal/webrtc/manager.go b/internal/webrtc/manager.go index cfc3c344..96bb8f3a 100644 --- a/internal/webrtc/manager.go +++ b/internal/webrtc/manager.go @@ -28,8 +28,8 @@ type WebRTCManagerCtx struct { logger zerolog.Logger videoTrack *webrtc.TrackLocalStaticSample audioTrack *webrtc.TrackLocalStaticSample - videoCodec codec.RTP - audioCodec codec.RTP + videoCodec codec.RTPCodec + audioCodec codec.RTPCodec desktop types.DesktopManager capture types.CaptureManager config *config.WebRTC