mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
WebRTC congestion control (#26)
* Add congestion control * Improve stream matching, add manual stream selection, add metrics * Use a ticker for bitrate estimation and make bandwidth drops switch to lower streams more aggressively * Missing signal response, fix video auto bug * Remove redundant mutex * Bitrate history queue * Get bitrate fn support h264 & float64 --------- Co-authored-by: Aleksandar Sukovic <aleksandar.sukovic@gmail.com>
This commit is contained in:
@ -8,9 +8,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/PaesslerAG/gval"
|
||||
"github.com/pion/webrtc/v3/pkg/media"
|
||||
|
||||
"github.com/demodesk/neko/pkg/types/codec"
|
||||
"github.com/pion/webrtc/v3/pkg/media"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -20,16 +19,23 @@ var (
|
||||
type Sample media.Sample
|
||||
|
||||
type Receiver interface {
|
||||
SetStream(stream StreamSinkManager) error
|
||||
SetStream(stream StreamSinkManager) (changed bool, err error)
|
||||
RemoveStream()
|
||||
OnBitrateChange(f func(int) error)
|
||||
OnBitrateChange(f func(bitrate int) (changed bool, err error))
|
||||
OnVideoChange(f func(videoID string) (changed bool, err error))
|
||||
VideoAuto() bool
|
||||
SetVideoAuto(videoAuto bool)
|
||||
}
|
||||
|
||||
type BucketsManager interface {
|
||||
IDs() []string
|
||||
Codec() codec.RTPCodec
|
||||
SetReceiver(receiver Receiver) error
|
||||
SetReceiver(receiver Receiver)
|
||||
RemoveReceiver(receiver Receiver) error
|
||||
|
||||
DestroyAll()
|
||||
RecreateAll() error
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
type BroadcastManager interface {
|
||||
@ -48,6 +54,7 @@ type ScreencastManager interface {
|
||||
type StreamSinkManager interface {
|
||||
ID() string
|
||||
Codec() codec.RTPCodec
|
||||
Bitrate() int
|
||||
|
||||
AddListener(listener *func(sample Sample)) error
|
||||
RemoveListener(listener *func(sample Sample)) error
|
||||
@ -55,6 +62,9 @@ type StreamSinkManager interface {
|
||||
|
||||
ListenersCount() int
|
||||
Started() bool
|
||||
|
||||
CreatePipeline() error
|
||||
DestroyPipeline()
|
||||
}
|
||||
|
||||
type StreamSrcManager interface {
|
||||
@ -201,17 +211,33 @@ func (config *VideoConfig) GetBitrateFn(getScreen func() *ScreenSize) func() (in
|
||||
}),
|
||||
}
|
||||
|
||||
// TOOD: do not read target-bitrate from pipeline, but only from config.
|
||||
|
||||
// TODO: This is only for vp8.
|
||||
expr, ok := config.GstParams["target-bitrate"]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("target-bitrate not found")
|
||||
// TODO: This is only for h264.
|
||||
expr, ok = config.GstParams["bitrate"]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("bitrate not found")
|
||||
}
|
||||
}
|
||||
|
||||
targetBitrate, err := gval.Evaluate(expr, values, language...)
|
||||
bitrate, err := gval.Evaluate(expr, values, language...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, fmt.Errorf("failed to evaluate bitrate: %w", err)
|
||||
}
|
||||
|
||||
return targetBitrate.(int), nil
|
||||
var bitrateInt int
|
||||
switch val := bitrate.(type) {
|
||||
case int:
|
||||
bitrateInt = val
|
||||
case float64:
|
||||
bitrateInt = (int)(val)
|
||||
default:
|
||||
return 0, fmt.Errorf("bitrate is not int or float64")
|
||||
}
|
||||
|
||||
return bitrateInt, nil
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,10 @@ type SystemDisconnect struct {
|
||||
type SignalProvide struct {
|
||||
SDP string `json:"sdp"`
|
||||
ICEServers []types.ICEServer `json:"iceservers"`
|
||||
Video string `json:"video"` // TODO: Refactor.
|
||||
// TODO: Use SignalVideo struct.
|
||||
Video string `json:"video"`
|
||||
Bitrate int `json:"bitrate"`
|
||||
VideoAuto bool `json:"video_auto"`
|
||||
}
|
||||
|
||||
type SignalCandidate struct {
|
||||
@ -60,8 +63,9 @@ type SignalDescription struct {
|
||||
}
|
||||
|
||||
type SignalVideo struct {
|
||||
Video string `json:"video"` // TODO: Refactor.
|
||||
Bitrate int `json:"bitrate"`
|
||||
Video string `json:"video"`
|
||||
Bitrate int `json:"bitrate"`
|
||||
VideoAuto bool `json:"video_auto"`
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
|
@ -25,8 +25,11 @@ type WebRTCPeer interface {
|
||||
SetCandidate(candidate webrtc.ICECandidateInit) error
|
||||
|
||||
SetVideoBitrate(bitrate int) error
|
||||
GetVideoId() string
|
||||
SetVideoID(videoID string) error
|
||||
GetVideoID() string
|
||||
SetPaused(isPaused bool) error
|
||||
SetVideoAuto(auto bool)
|
||||
VideoAuto() bool
|
||||
|
||||
SendCursorPosition(x, y int) error
|
||||
SendCursorImage(cur *CursorImage, img []byte) error
|
||||
@ -40,6 +43,6 @@ type WebRTCManager interface {
|
||||
|
||||
ICEServers() []ICEServer
|
||||
|
||||
CreatePeer(session Session, bitrate int) (*webrtc.SessionDescription, error)
|
||||
CreatePeer(session Session, bitrate int, videoAuto bool) (*webrtc.SessionDescription, error)
|
||||
SetCursorPosition(x, y int)
|
||||
}
|
||||
|
Reference in New Issue
Block a user