This commit is contained in:
Miroslav Šedivý 2023-01-28 22:08:36 +01:00
parent dfe8b8b57d
commit ee13e40d4c
16 changed files with 135 additions and 103 deletions

View File

@ -18,7 +18,6 @@ type CaptureManagerCtx struct {
broadcast *BroacastManagerCtx
audio *StreamSinkManagerCtx
video *StreamSinkManagerCtx
}
func New(desktop types.DesktopManager, config *config.Capture) *CaptureManagerCtx {
@ -53,7 +52,8 @@ func (manager *CaptureManagerCtx) Start() {
go func() {
for {
_ = <- manager.desktop.GetBeforeScreenSizeChangeChannel()
<-manager.desktop.GetBeforeScreenSizeChangeChannel()
if manager.video.Started() {
manager.video.destroyPipeline()
}
@ -66,7 +66,8 @@ func (manager *CaptureManagerCtx) Start() {
go func() {
for {
framerate := <- manager.desktop.GetAfterScreenSizeChangeChannel();
framerate := <-manager.desktop.GetAfterScreenSizeChangeChannel()
if manager.video.Started() {
manager.video.SetChangeFramerate(framerate)
err := manager.video.createPipeline()

View File

@ -110,6 +110,7 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
// https://gstreamer.freedesktop.org/documentation/aom/av1enc.html?gi-language=c
// gstreamer1.0-plugins-bad
// av1enc usage-profile=1
// TODO: check for plugin.
if err := gst.CheckPlugins([]string{"ximagesrc", "vpx"}); err != nil {
return "", err
}
@ -120,7 +121,7 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
fmt.Sprintf("target-bitrate=%d", bitrate*650),
"cpu-used=4",
"end-usage=cbr",
// "usage-profile=realtime",
// "usage-profile=realtime",
"undershoot=95",
"keyframe-max-dist=25",
"min-quantizer=4",

View File

@ -2,9 +2,9 @@ package capture
import (
"errors"
"sync"
"regexp"
"strconv"
"sync"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
@ -143,7 +143,7 @@ func (manager *StreamSinkManagerCtx) createPipeline() error {
if manager.changeFramerate > 0 && manager.adaptiveFramerate {
m1 := regexp.MustCompile(`framerate=\d+/1`)
pipelineStr = m1.ReplaceAllString(pipelineStr, "framerate=" + strconv.FormatInt(int64(manager.changeFramerate), 10) + "/1")
pipelineStr = m1.ReplaceAllString(pipelineStr, "framerate="+strconv.FormatInt(int64(manager.changeFramerate), 10)+"/1")
}
manager.logger.Info().
@ -180,7 +180,7 @@ func (manager *StreamSinkManagerCtx) destroyPipeline() {
manager.pipeline = nil
}
func (manager *StreamSinkManagerCtx) GetSampleChannel() (chan types.Sample) {
func (manager *StreamSinkManagerCtx) GetSampleChannel() chan types.Sample {
if manager.pipeline != nil {
return manager.pipeline.Sample
}

View File

@ -28,8 +28,8 @@ func New(config *config.Desktop) *DesktopManagerCtx {
return &DesktopManagerCtx{
logger: log.With().Str("module", "desktop").Logger(),
shutdown: make(chan struct{}),
beforeScreenSizeChangeChannel: make (chan bool),
afterScreenSizeChangeChannel: make (chan int16),
beforeScreenSizeChangeChannel: make(chan bool),
afterScreenSizeChangeChannel: make(chan int16),
config: config,
}
}
@ -50,12 +50,12 @@ func (manager *DesktopManagerCtx) Start() {
go func() {
for {
desktopErrorMessage := <- xevent.EventErrorChannel
msg := <-xevent.EventErrorChannel
manager.logger.Warn().
Uint8("error_code", desktopErrorMessage.Error_code).
Str("message", desktopErrorMessage.Message).
Uint8("request_code", desktopErrorMessage.Request_code).
Uint8("minor_code", desktopErrorMessage.Minor_code).
Uint8("error_code", msg.Error_code).
Str("message", msg.Message).
Uint8("request_code", msg.Request_code).
Uint8("minor_code", msg.Minor_code).
Msg("X event error occurred")
}
}()
@ -79,11 +79,11 @@ func (manager *DesktopManagerCtx) Start() {
}()
}
func (manager *DesktopManagerCtx) GetBeforeScreenSizeChangeChannel() (chan bool) {
func (manager *DesktopManagerCtx) GetBeforeScreenSizeChangeChannel() chan bool {
return manager.beforeScreenSizeChangeChannel
}
func (manager *DesktopManagerCtx) GetAfterScreenSizeChangeChannel() (chan int16) {
func (manager *DesktopManagerCtx) GetAfterScreenSizeChangeChannel() chan int16 {
return manager.afterScreenSizeChangeChannel
}

View File

@ -5,22 +5,22 @@ import (
"m1k1o/neko/internal/types"
)
func (manager *DesktopManagerCtx) GetCursorChangedChannel() (chan uint64) {
func (manager *DesktopManagerCtx) GetCursorChangedChannel() chan uint64 {
return xevent.CursorChangedChannel
}
func (manager *DesktopManagerCtx) GetClipboardUpdatedChannel() (chan bool) {
func (manager *DesktopManagerCtx) GetClipboardUpdatedChannel() chan bool {
return xevent.ClipboardUpdatedChannel
}
func (manager *DesktopManagerCtx) GetFileChooserDialogOpenedChannel() (chan bool) {
func (manager *DesktopManagerCtx) GetFileChooserDialogOpenedChannel() chan bool {
return xevent.FileChooserDialogOpenedChannel
}
func (manager *DesktopManagerCtx) GetFileChooserDialogClosedChannel() (chan bool) {
func (manager *DesktopManagerCtx) GetFileChooserDialogClosedChannel() chan bool {
return xevent.FileChooserDialogClosedChannel
}
func (manager *DesktopManagerCtx) GetEventErrorChannel() (chan types.DesktopErrorMessage) {
func (manager *DesktopManagerCtx) GetEventErrorChannel() chan types.DesktopErrorMessage {
return xevent.EventErrorChannel
}

View File

@ -9,6 +9,7 @@ import "C"
import (
"unsafe"
"m1k1o/neko/internal/types"
)
@ -25,20 +26,22 @@ func init() {
FileChooserDialogOpenedChannel = make(chan bool)
EventErrorChannel = make(chan types.DesktopErrorMessage)
// Dummy goroutines since there is no consumer for the channel otherwise
go func() {
for {
_ = <-CursorChangedChannel
// TODO: Unused.
<-CursorChangedChannel
}
}()
go func() {
for {
_ = <-FileChooserDialogClosedChannel
// TODO: Unused.
<-FileChooserDialogClosedChannel
}
}()
go func() {
for {
_ = <-FileChooserDialogOpenedChannel
// TODO: Unused.
<-FileChooserDialogOpenedChannel
}
}()
}
@ -72,7 +75,12 @@ func goXEventUnmapNotify(window C.Window) {
//export goXEventError
func goXEventError(event *C.XErrorEvent, message *C.char) {
EventErrorChannel <- types.DesktopErrorMessage{ uint8(event.error_code), C.GoString(message), uint8(event.request_code), uint8(event.minor_code) }
EventErrorChannel <- types.DesktopErrorMessage{
Error_code: uint8(event.error_code),
Message: C.GoString(message),
Request_code: uint8(event.request_code),
Minor_code: uint8(event.minor_code),
}
}
//export goXEventActive

View File

@ -50,11 +50,16 @@ func (manager *SessionManager) New(id string, admin bool, socket types.WebSocket
manager.capture.Video().AddListener()
manager.mu.Unlock()
manager.sessionChannel <- types.SessionInformation{ "created", id, session }
manager.sessionChannel <- types.SessionInformation{
Type: "created",
Id: id,
Session: session,
}
go func() {
for {
_ = <- manager.hostChannel
// TODO: Unused.
<-manager.hostChannel
}
}()
return session
@ -76,7 +81,10 @@ func (manager *SessionManager) SetHost(id string) error {
if ok {
manager.host = id
manager.hostChannel <- types.HostInformation{ "host", id }
manager.hostChannel <- types.HostInformation{
Type: "host",
Id: id,
}
return nil
}
@ -94,7 +102,10 @@ func (manager *SessionManager) GetHost() (types.Session, bool) {
func (manager *SessionManager) ClearHost() {
id := manager.host
manager.host = ""
manager.hostChannel <- types.HostInformation{ "host_cleared", id }
manager.hostChannel <- types.HostInformation{
Type: "host_cleared",
Id: id,
}
}
func (manager *SessionManager) Has(id string) bool {
@ -171,7 +182,11 @@ func (manager *SessionManager) Destroy(id string) {
manager.capture.Video().RemoveListener()
manager.mu.Unlock()
manager.sessionChannel <- types.SessionInformation{ "destroyed", id, session }
manager.sessionChannel <- types.SessionInformation{
Type: "destroyed",
Id: id,
Session: session,
}
manager.logger.Err(err).Str("session_id", id).Msg("destroying session")
return
}
@ -229,10 +244,10 @@ func (manager *SessionManager) AdminBroadcast(v interface{}, exclude interface{}
return nil
}
func (manager *SessionManager) GetSessionChannel() (chan types.SessionInformation) {
func (manager *SessionManager) GetSessionChannel() chan types.SessionInformation {
return manager.sessionChannel
}
func (manager *SessionManager) GetHostChannel() (chan types.HostInformation) {
func (manager *SessionManager) GetHostChannel() chan types.HostInformation {
return manager.hostChannel
}

View File

@ -78,7 +78,11 @@ func (session *Session) SetPeer(peer types.Peer) error {
func (session *Session) SetConnected(connected bool) error {
session.connected = connected
if connected {
session.manager.sessionChannel <- types.SessionInformation{ "connected", session.id, session }
session.manager.sessionChannel <- types.SessionInformation{
Type: "connected",
Id: session.id,
Session: session,
}
}
return nil
}

View File

@ -25,7 +25,7 @@ type StreamSinkManager interface {
ListenersCount() int
Started() bool
GetSampleChannel() (chan Sample)
GetSampleChannel() chan Sample
SetChangeFramerate(rate int16)
SetAdaptiveFramerate(allow bool)
}

View File

@ -116,6 +116,7 @@ func H264() RTPCodec {
},
}
}
// TODO: Profile ID.
func AV1() RTPCodec {
return RTPCodec{

View File

@ -43,8 +43,8 @@ type DesktopErrorMessage struct {
type DesktopManager interface {
Start()
Shutdown() error
GetBeforeScreenSizeChangeChannel() (chan bool)
GetAfterScreenSizeChangeChannel() (chan int16)
GetBeforeScreenSizeChangeChannel() chan bool
GetAfterScreenSizeChangeChannel() chan int16
// clipboard
ReadClipboard() string
@ -72,9 +72,9 @@ type DesktopManager interface {
GetScreenshotImage() *image.RGBA
// xevent
GetCursorChangedChannel() (chan uint64)
GetClipboardUpdatedChannel() (chan bool)
GetFileChooserDialogOpenedChannel() (chan bool)
GetFileChooserDialogClosedChannel() (chan bool)
GetEventErrorChannel() (chan DesktopErrorMessage)
GetCursorChangedChannel() chan uint64
GetClipboardUpdatedChannel() chan bool
GetFileChooserDialogOpenedChannel() chan bool
GetFileChooserDialogClosedChannel() chan bool
GetEventErrorChannel() chan DesktopErrorMessage
}

View File

@ -57,6 +57,6 @@ type SessionManager interface {
Clear() error
Broadcast(v interface{}, exclude interface{}) error
AdminBroadcast(v interface{}, exclude interface{}) error
GetSessionChannel() (chan SessionInformation)
GetHostChannel() (chan HostInformation)
GetSessionChannel() chan SessionInformation
GetHostChannel() chan HostInformation
}

View File

@ -62,7 +62,8 @@ func (manager *WebRTCManager) Start() {
time.Sleep(50 * time.Millisecond)
continue
}
newSample := <- manager.capture.Audio().GetSampleChannel()
newSample := <-manager.capture.Audio().GetSampleChannel()
err := manager.audioTrack.WriteSample(media.Sample(newSample))
if err != nil && errors.Is(err, io.ErrClosedPipe) {
manager.logger.Warn().Err(err).Msg("audio pipeline failed to write")
@ -87,7 +88,8 @@ func (manager *WebRTCManager) Start() {
time.Sleep(50 * time.Millisecond)
continue
}
newSample := <- manager.capture.Video().GetSampleChannel()
newSample := <-manager.capture.Video().GetSampleChannel()
err := manager.videoTrack.WriteSample(media.Sample(newSample))
if err != nil && errors.Is(err, io.ErrClosedPipe) {
manager.logger.Warn().Err(err).Msg("video pipeline failed to write")

View File

@ -101,9 +101,9 @@ type WebSocketHandler struct {
}
func (ws *WebSocketHandler) Start() {
go func () {
go func() {
for {
channelMessage := <- ws.sessions.GetSessionChannel()
channelMessage := <-ws.sessions.GetSessionChannel()
switch channelMessage.Type {
case "created":
@ -189,7 +189,7 @@ func (ws *WebSocketHandler) Start() {
go func() {
for {
_ = <- ws.desktop.GetClipboardUpdatedChannel()
_ = <-ws.desktop.GetClipboardUpdatedChannel()
session, ok := ws.sessions.GetHost()
if !ok {
return