optimize remote desktop, hvnc and webcam stuff. Fix issues with webcam frames getting super slow out of nowhere because of backup. Also remove compression since we rarely use it + H264 already compresses. Most things we send either way are so small where compression just adds CPU overhead that isn't needed.

This commit is contained in:
KingKDot
2026-03-13 09:28:16 -05:00
parent 5ceea3d34c
commit 225bc9e377
10 changed files with 241 additions and 107 deletions
@@ -7,17 +7,21 @@ import (
"fmt"
"image"
"sync"
"sync/atomic"
x264 "github.com/gen2brain/x264-go"
)
var (
h264Mu sync.Mutex
h264Enc *x264.Encoder
h264Buf bytes.Buffer
h264Width int
h264Height int
h264LastErr error
h264Mu sync.Mutex
h264Enc *x264.Encoder
h264Buf bytes.Buffer
h264Width int
h264Height int
h264FPS int
h264LastErr error
h264Scratch []byte
h264TargetFPS atomic.Int64 // set by the stream handler; default 60
)
func encodeH264Frame(img *image.RGBA) ([]byte, error) {
@@ -40,9 +44,17 @@ func encodeH264Frame(img *image.RGBA) ([]byte, error) {
}
h264LastErr = nil
out := make([]byte, h264Buf.Len())
copy(out, h264Buf.Bytes())
return out, nil
n := h264Buf.Len()
if n == 0 {
return nil, nil
}
if cap(h264Scratch) < n {
h264Scratch = make([]byte, n, n+(n/4))
} else {
h264Scratch = h264Scratch[:n]
}
copy(h264Scratch, h264Buf.Bytes())
return h264Scratch, nil
}
func h264Available() bool {
@@ -58,8 +70,27 @@ func h264AvailabilityDetail() string {
return "cgo build with x264-go"
}
// SetH264TargetFPS sets the frame rate hint for the x264 encoder so its
// rate-control matches the actual capture cadence. Call this before (or
// when) streaming starts. The encoder is automatically re-created on the
// next frame if the value differs from the current one.
func SetH264TargetFPS(fps int) {
if fps < 1 {
fps = 1
}
h264TargetFPS.Store(int64(fps))
}
func activeH264FPS() int {
if v := int(h264TargetFPS.Load()); v > 0 {
return v
}
return 60 // sensible default for desktop streaming
}
func ensureH264EncoderLocked(width, height int) error {
if h264Enc != nil && h264Width == width && h264Height == height {
fps := activeH264FPS()
if h264Enc != nil && h264Width == width && h264Height == height && h264FPS == fps {
return nil
}
@@ -68,12 +99,12 @@ func ensureH264EncoderLocked(width, height int) error {
opts := &x264.Options{
Width: width,
Height: height,
FrameRate: 120,
Tune: "zerolatency,fastdecode",
Preset: "ultrafast",
Profile: "baseline",
FrameRate: fps,
Tune: "zerolatency",
Preset: "veryfast",
Profile: "main",
RateControl: "crf",
RateConstant: 30,
RateConstant: 23,
LogLevel: x264.LogError,
}
@@ -85,6 +116,7 @@ func ensureH264EncoderLocked(width, height int) error {
h264Enc = enc
h264Width = width
h264Height = height
h264FPS = fps
return nil
}
@@ -101,5 +133,6 @@ func closeH264EncoderLocked() {
}
h264Width = 0
h264Height = 0
h264FPS = 0
h264Buf.Reset()
}