refactor functions

This commit is contained in:
Siyuan Miao 2025-06-24 07:10:54 +00:00
parent fb166e9d58
commit 3fa3af2d5b
13 changed files with 185 additions and 522 deletions

View File

@ -35,24 +35,24 @@ func updateDisplay() {
nativeInstance.UpdateLabelIfChanged("home_info_ipv4_addr", networkState.IPv4String())
nativeInstance.UpdateLabelAndChangeVisibility("home_info_ipv6_addr", networkState.IPv6String())
nativeInstance.ObjHide("menu_btn_network")
nativeInstance.ObjHide("menu_btn_access")
nativeInstance.UIObjHide("menu_btn_network")
nativeInstance.UIObjHide("menu_btn_access")
nativeInstance.UpdateLabelIfChanged("home_info_mac_addr", networkState.MACString())
if usbState == "configured" {
nativeInstance.UpdateLabelIfChanged("usb_status_label", "Connected")
_, _ = nativeInstance.ObjSetState("usb_status", "LV_STATE_DEFAULT")
_, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DEFAULT")
} else {
nativeInstance.UpdateLabelIfChanged("usb_status_label", "Disconnected")
_, _ = nativeInstance.ObjSetState("usb_status", "LV_STATE_DISABLED")
_, _ = nativeInstance.UIObjSetState("usb_status", "LV_STATE_DISABLED")
}
if lastVideoState.Ready {
nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Connected")
_, _ = nativeInstance.ObjSetState("hdmi_status", "LV_STATE_DEFAULT")
_, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DEFAULT")
} else {
nativeInstance.UpdateLabelIfChanged("hdmi_status_label", "Disconnected")
_, _ = nativeInstance.ObjSetState("hdmi_status", "LV_STATE_DISABLED")
_, _ = nativeInstance.UIObjSetState("hdmi_status", "LV_STATE_DISABLED")
}
nativeInstance.UpdateLabelIfChanged("cloud_status_label", fmt.Sprintf("%d active", actionSessions))
@ -63,20 +63,20 @@ func updateDisplay() {
}
if cloudConnectionState == CloudConnectionStateNotConfigured {
_, _ = nativeInstance.ObjHide("cloud_status_icon")
_, _ = nativeInstance.UIObjHide("cloud_status_icon")
} else {
_, _ = nativeInstance.ObjShow("cloud_status_icon")
_, _ = nativeInstance.UIObjShow("cloud_status_icon")
}
switch cloudConnectionState {
case CloudConnectionStateDisconnected:
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud_disconnected")
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud_disconnected")
stopCloudBlink()
case CloudConnectionStateConnecting:
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud")
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
startCloudBlink()
case CloudConnectionStateConnected:
_, _ = nativeInstance.ImgSetSrc("cloud_status_icon", "cloud")
_, _ = nativeInstance.UIObjSetImageSrc("cloud_status_icon", "cloud")
stopCloudBlink()
}
}
@ -100,9 +100,9 @@ func startCloudBlink() {
if cloudConnectionState != CloudConnectionStateConnecting {
continue
}
_, _ = nativeInstance.ObjFadeOut("cloud_status_icon", 1000)
_, _ = nativeInstance.UIObjFadeOut("cloud_status_icon", 1000)
time.Sleep(1000 * time.Millisecond)
_, _ = nativeInstance.ObjFadeIn("cloud_status_icon", 1000)
_, _ = nativeInstance.UIObjFadeIn("cloud_status_icon", 1000)
time.Sleep(1000 * time.Millisecond)
}
}()
@ -347,7 +347,7 @@ func initDisplay() {
go func() {
displayLogger.Info().Msg("setting initial display contents")
time.Sleep(500 * time.Millisecond)
_, _ = nativeInstance.DispSetRotation(config.DisplayRotation)
_, _ = nativeInstance.DisplaySetRotation(config.DisplayRotation)
updateStaticContents()
displayInited = true
displayLogger.Info().Msg("display inited")

View File

@ -12,7 +12,7 @@
#include "edid.h"
#include "ctrl.h"
#include <lvgl.h>
#include "ui/vars.h"
#include "ui_index.h"
#include "log.h"
#include "log_handler.h"
@ -154,8 +154,24 @@ lv_obj_flag_t str_to_lv_obj_flag(const char *flag)
}
}
void jetkvm_set_app_version(const char *version) {
set_var_app_version(version);
void jetkvm_ui_set_var(const char *name, const char *value) {
for (int i = 0; i < ui_vars_size; i++) {
if (strcmp(ui_vars[i].name, name) == 0) {
ui_vars[i].setter(value);
return;
}
}
log_error("variable %s not found", name);
}
const char *jetkvm_ui_get_var(const char *name) {
for (int i = 0; i < ui_vars_size; i++) {
if (strcmp(ui_vars[i].name, name) == 0) {
return ui_vars[i].getter();
}
}
log_error("variable %s not found", name);
return NULL;
}
void jetkvm_ui_init() {

View File

@ -22,7 +22,8 @@ typedef void (jetkvm_video_handler_t)(const uint8_t *frame, ssize_t len);
void jetkvm_set_log_handler(jetkvm_log_handler_t *handler);
void jetkvm_set_video_handler(jetkvm_video_handler_t *handler);
void jetkvm_set_app_version(const char *version);
void jetkvm_ui_set_var(const char *name, const char *value);
const char *jetkvm_ui_get_var(const char *name);
void jetkvm_ui_init();
void jetkvm_ui_tick();

View File

@ -19,6 +19,14 @@ done)
};
const int ui_images_size = sizeof(ui_images) / sizeof(ui_images[0]);
ui_var_map ui_vars[] = {
$(grep 'extern const char \*get_var_' ui/vars.h | sed 's/extern const char \*get_var_//g' | sed 's/();//g' | sed 's/\r//' | while read -r line; do
echo " {\"$line\", &get_var_$line, &set_var_$line},"
done)
};
const int ui_vars_size = sizeof(ui_vars) / sizeof(ui_vars[0]);
EOF
echo "ui_index.c has been generated successfully."

View File

@ -4,6 +4,7 @@
#include "ui/ui.h"
#include "ui/screens.h"
#include "ui/images.h"
#include "ui/vars.h"
typedef struct {
const char *name;
@ -21,5 +22,13 @@ typedef struct {
extern ui_img_map ui_images[];
extern const int ui_images_size;
typedef struct {
const char *name;
const char *(*getter)();
void (*setter)(const char *value);
} ui_var_map;
extern ui_var_map ui_vars[];
extern const int ui_vars_size;
#endif // UI_INDEX_H

View File

@ -1,282 +0,0 @@
//go:build linux
package native
import (
"fmt"
"strconv"
"sync"
"time"
"unsafe"
"github.com/rs/zerolog"
)
// #cgo LDFLAGS: -Lcgo/build -Lcgo/build/lib -ljknative -llvgl
// #cgo CFLAGS: -Icgo -Icgo/ui -Icgo/build/_deps/lvgl-src
// #include "ctrl.h"
// #include <stdlib.h>
// typedef const char cchar_t;
// typedef const uint8_t cuint8_t;
// extern void jetkvm_video_state_handler(jetkvm_video_state_t *state);
// static inline void jetkvm_setup_video_state_handler() {
// jetkvm_set_video_state_handler(&jetkvm_video_state_handler);
// }
// extern void jetkvm_go_log_handler(int level, cchar_t *filename, cchar_t *funcname, int line, cchar_t *message);
// static inline void jetkvm_setup_log_handler() {
// jetkvm_set_log_handler(&jetkvm_go_log_handler);
// }
// extern void jetkvm_video_handler(cuint8_t *frame, ssize_t len);
// static inline void jetkvm_setup_video_handler() {
// jetkvm_set_video_handler(&jetkvm_video_handler);
// }
import "C"
var (
jkInstance *Native
jkInstanceLock sync.RWMutex
jkVideoChan chan []byte = make(chan []byte)
)
func setUpJkInstance(instance *Native) {
jkInstanceLock.Lock()
defer jkInstanceLock.Unlock()
if jkInstance == nil {
jkInstance = instance
}
if jkInstance != instance {
panic("jkInstance is already set")
}
}
//export jetkvm_video_state_handler
func jetkvm_video_state_handler(state *C.jetkvm_video_state_t) {
jkInstanceLock.RLock()
defer jkInstanceLock.RUnlock()
if jkInstance != nil {
// convert state to VideoState
videoState := VideoState{
Ready: bool(state.ready),
Error: C.GoString(state.error),
Width: int(state.width),
Height: int(state.height),
FramePerSecond: float64(state.frame_per_second),
}
jkInstance.handleVideoStateMessage(videoState)
}
}
//export jetkvm_go_log_handler
func jetkvm_go_log_handler(level C.int, filename *C.cchar_t, funcname *C.cchar_t, line C.int, message *C.cchar_t) {
l := nativeLogger.With().
Str("file", C.GoString(filename)).
Str("function", C.GoString(funcname)).
Int("line", int(line)).
Logger()
gLevel := zerolog.Level(level)
switch gLevel {
case zerolog.DebugLevel:
l.Debug().Msg(C.GoString(message))
case zerolog.InfoLevel:
l.Info().Msg(C.GoString(message))
case zerolog.WarnLevel:
l.Warn().Msg(C.GoString(message))
case zerolog.ErrorLevel:
l.Error().Msg(C.GoString(message))
case zerolog.PanicLevel:
l.Panic().Msg(C.GoString(message))
case zerolog.FatalLevel:
l.Fatal().Msg(C.GoString(message))
case zerolog.TraceLevel:
l.Trace().Msg(C.GoString(message))
case zerolog.NoLevel:
l.Info().Msg(C.GoString(message))
default:
l.Info().Msg(C.GoString(message))
}
}
//export jetkvm_video_handler
func jetkvm_video_handler(frame *C.cuint8_t, len C.ssize_t) {
jkVideoChan <- C.GoBytes(unsafe.Pointer(frame), C.int(len))
}
func setVideoStateHandler() {
C.jetkvm_setup_video_state_handler()
}
func setLogHandler() {
C.jetkvm_setup_log_handler()
}
func setVideoHandler() {
C.jetkvm_setup_video_handler()
}
func (n *Native) StartNativeVideo() {
setUpJkInstance(n)
setVideoStateHandler()
setLogHandler()
setVideoHandler()
C.jetkvm_set_app_version(C.CString(n.appVersion.String()))
C.jetkvm_ui_init()
n.UpdateLabelIfChanged("boot_screen_version", n.appVersion.String())
go func() {
for {
C.jetkvm_ui_tick()
time.Sleep(5 * time.Millisecond)
}
}()
if C.jetkvm_video_init() != 0 {
nativeLogger.Error().Msg("failed to initialize video")
return
}
C.jetkvm_video_start()
close(n.ready)
}
func (n *Native) StopNativeVideo() {
C.jetkvm_video_stop()
}
func (n *Native) SwitchToScreen(screen string) {
screenCStr := C.CString(screen)
defer C.free(unsafe.Pointer(screenCStr))
C.jetkvm_ui_load_screen(screenCStr)
}
func (n *Native) GetCurrentScreen() string {
screenCStr := C.jetkvm_ui_get_current_screen()
return C.GoString(screenCStr)
}
func (n *Native) ObjSetState(objName string, state string) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
stateCStr := C.CString(state)
defer C.free(unsafe.Pointer(stateCStr))
C.jetkvm_ui_set_state(objNameCStr, stateCStr)
return true, nil
}
func (n *Native) ObjAddFlag(objName string, flag string) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
flagCStr := C.CString(flag)
defer C.free(unsafe.Pointer(flagCStr))
C.jetkvm_ui_add_flag(objNameCStr, flagCStr)
return true, nil
}
func (n *Native) ObjClearFlag(objName string, flag string) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
flagCStr := C.CString(flag)
defer C.free(unsafe.Pointer(flagCStr))
C.jetkvm_ui_clear_flag(objNameCStr, flagCStr)
return true, nil
}
func (n *Native) ObjHide(objName string) (bool, error) {
return n.ObjAddFlag(objName, "LV_OBJ_FLAG_HIDDEN")
}
func (n *Native) ObjShow(objName string) (bool, error) {
return n.ObjClearFlag(objName, "LV_OBJ_FLAG_HIDDEN")
}
func (n *Native) ObjSetOpacity(objName string, opacity int) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
C.jetkvm_ui_set_opacity(objNameCStr, C.u_int8_t(opacity))
return true, nil
}
func (n *Native) ObjFadeIn(objName string, duration uint32) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
C.jetkvm_ui_fade_in(objNameCStr, C.u_int32_t(duration))
return true, nil
}
func (n *Native) ObjFadeOut(objName string, duration uint32) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
C.jetkvm_ui_fade_out(objNameCStr, C.u_int32_t(duration))
return true, nil
}
func (n *Native) LabelSetText(objName string, text string) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
textCStr := C.CString(text)
defer C.free(unsafe.Pointer(textCStr))
ret := C.jetkvm_ui_set_text(objNameCStr, textCStr)
if ret < 0 {
return false, fmt.Errorf("failed to set text: %d", ret)
}
return ret == 0, nil
}
func (n *Native) ImgSetSrc(objName string, src string) (bool, error) {
objNameCStr := C.CString(objName)
defer C.free(unsafe.Pointer(objNameCStr))
srcCStr := C.CString(src)
defer C.free(unsafe.Pointer(srcCStr))
C.jetkvm_ui_set_image(objNameCStr, srcCStr)
return true, nil
}
func (n *Native) DispSetRotation(rotation string) (bool, error) {
rotationInt, err := strconv.Atoi(rotation)
if err != nil {
return false, err
}
nativeLogger.Info().Int("rotation", rotationInt).Msg("setting rotation")
// C.jetkvm_ui_set_rotation(C.u_int8_t(rotationInt))
return true, nil
}
func (n *Native) GetStreamQualityFactor() (float64, error) {
factor := C.jetkvm_video_get_quality_factor()
return float64(factor), nil
}
func (n *Native) SetStreamQualityFactor(factor float64) error {
C.jetkvm_video_set_quality_factor(C.float(factor))
return nil
}
func (n *Native) GetEDID() (string, error) {
edidCStr := C.jetkvm_video_get_edid_hex()
return C.GoString(edidCStr), nil
}
func (n *Native) SetEDID(edid string) error {
edidCStr := C.CString(edid)
defer C.free(unsafe.Pointer(edidCStr))
C.jetkvm_video_set_edid(edidCStr)
return nil
}

View File

@ -1,88 +0,0 @@
//go:build !linux
package native
func panicNotImplemented() {
panic("not supported")
}
func (n *Native) StartNativeVideo() {
panicNotImplemented()
}
func (n *Native) StopNativeVideo() {
panicNotImplemented()
}
func (n *Native) SwitchToScreen(screen string) {
panicNotImplemented()
}
func (n *Native) GetCurrentScreen() string {
panicNotImplemented()
}
func (n *Native) ObjSetState(objName string, state string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjAddFlag(objName string, flag string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjClearFlag(objName string, flag string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjHide(objName string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjShow(objName string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjSetOpacity(objName string, opacity int) (bool, error) { // nolint:unused
panicNotImplemented()
return false, nil
}
func (n *Native) ObjFadeIn(objName string, duration uint32) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ObjFadeOut(objName string, duration uint32) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) LabelSetText(objName string, text string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) ImgSetSrc(objName string, src string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) DispSetRotation(rotation string) (bool, error) {
panicNotImplemented()
return false, nil
}
func (n *Native) GetStreamQualityFactor() (float64, error) {
panicNotImplemented()
return 0, nil
}
func (n *Native) SetStreamQualityFactor(factor float64) error {
panicNotImplemented()
return nil
}

View File

@ -1,11 +1,74 @@
package native
import "slices"
import (
"slices"
"time"
)
func (n *Native) setUIVars() {
uiSetVar("app_version", n.appVersion.String())
}
func (n *Native) initUI() {
uiInit()
n.setUIVars()
}
func (n *Native) tickUI() {
for {
uiTick()
time.Sleep(5 * time.Millisecond)
}
}
func (n *Native) UIObjHide(objName string) (bool, error) {
return uiObjHide(objName)
}
func (n *Native) UIObjShow(objName string) (bool, error) {
return uiObjShow(objName)
}
func (n *Native) UIObjSetState(objName string, state string) (bool, error) {
return uiObjSetState(objName, state)
}
func (n *Native) UIObjAddFlag(objName string, flag string) (bool, error) {
return uiObjAddFlag(objName, flag)
}
func (n *Native) UIObjClearFlag(objName string, flag string) (bool, error) {
return uiObjClearFlag(objName, flag)
}
func (n *Native) UIObjSetOpacity(objName string, opacity int) (bool, error) {
return uiObjSetOpacity(objName, opacity)
}
func (n *Native) UIObjFadeIn(objName string, duration uint32) (bool, error) {
return uiObjFadeIn(objName, duration)
}
func (n *Native) UIObjFadeOut(objName string, duration uint32) (bool, error) {
return uiObjFadeOut(objName, duration)
}
func (n *Native) UIObjSetLabelText(objName string, text string) (bool, error) {
return uiLabelSetText(objName, text)
}
func (n *Native) UIObjSetImageSrc(objName string, image string) (bool, error) {
return uiImgSetSrc(objName, image)
}
func (n *Native) DisplaySetRotation(rotation string) (bool, error) {
return uiDispSetRotation(rotation)
}
func (n *Native) UpdateLabelIfChanged(objName string, newText string) {
l := n.lD.Trace().Str("obj", objName).Str("text", newText)
changed, err := n.LabelSetText(objName, newText)
changed, err := n.UIObjSetLabelText(objName, newText)
if err != nil {
n.lD.Warn().Str("obj", objName).Str("text", newText).Err(err).Msg("failed to update label")
return
@ -21,27 +84,27 @@ func (n *Native) UpdateLabelIfChanged(objName string, newText string) {
func (n *Native) UpdateLabelAndChangeVisibility(objName string, newText string) {
containerName := objName + "_container"
if newText == "" {
_, _ = n.ObjHide(objName)
_, _ = n.ObjHide(containerName)
_, _ = n.UIObjHide(objName)
_, _ = n.UIObjHide(containerName)
} else {
_, _ = n.ObjShow(objName)
_, _ = n.ObjShow(containerName)
_, _ = n.UIObjShow(objName)
_, _ = n.UIObjShow(containerName)
}
n.UpdateLabelIfChanged(objName, newText)
}
func (n *Native) SwitchToScreenIf(screenName string, shouldSwitch []string) {
currentScreen := n.GetCurrentScreen()
currentScreen := uiGetCurrentScreen()
if currentScreen == screenName {
return
}
if !slices.Contains(shouldSwitch, currentScreen) {
displayLogger.Trace().Str("from", currentScreen).Str("to", screenName).Msg("skipping screen switch")
n.lD.Trace().Str("from", currentScreen).Str("to", screenName).Msg("skipping screen switch")
return
}
displayLogger.Info().Str("from", currentScreen).Str("to", screenName).Msg("switching screen")
n.SwitchToScreen(screenName)
n.lD.Info().Str("from", currentScreen).Str("to", screenName).Msg("switching screen")
uiSwitchToScreen(screenName)
}
func (n *Native) SwitchToScreenIfDifferent(screenName string) {

View File

@ -58,7 +58,7 @@
{
"objID": "316b04e4-a7de-4afc-c413-31f5f36d3843",
"fileName": "vars.c",
"template": "#include <string.h>\n#include \"vars.h\"\n\nchar app_version[100] = { 0 };\n\nconst char *get_var_app_version() {\n return app_version;\n}\n\nvoid set_var_app_version(const char *value) {\n strncpy(app_version, value, sizeof(app_version) / sizeof(char));\n app_version[sizeof(app_version) / sizeof(char) - 1] = 0;\n}\n"
"template": "#include <string.h>\n#include \"vars.h\"\n\nchar app_version[100] = { 0 };\nchar system_version[100] = { 0 };\n\nconst char *get_var_app_version() {\n return app_version;\n}\n\nconst char *get_var_system_version() {\n return system_version;\n}\n\nvoid set_var_app_version(const char *value) {\n strncpy(app_version, value, sizeof(app_version) / sizeof(char));\n app_version[sizeof(app_version) / sizeof(char) - 1] = 0;\n}\n\nvoid set_var_system_version(const char *value) {\n strncpy(system_version, value, sizeof(system_version) / sizeof(char));\n system_version[sizeof(system_version) / sizeof(char) - 1] = 0;\n}"
},
{
"objID": "cbe7cde1-8920-476a-b2a2-1761ae7451b0",
@ -124,6 +124,14 @@
"defaultValue": "\"\"",
"persistent": false,
"native": false
},
{
"objID": "f20790a9-e7dd-4537-f50b-c716cee2af24",
"name": "systemVersion",
"type": "string",
"defaultValue": "\"\"",
"persistent": false,
"native": false
}
],
"structures": [],
@ -4048,10 +4056,11 @@
},
"group": "",
"groupIndex": 0,
"text": "0.0.1",
"textType": "literal",
"text": "systemVersion",
"textType": "expression",
"longMode": "WRAP",
"recolor": false
"recolor": false,
"previewValue": "0.0.1"
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",
@ -4185,10 +4194,11 @@
},
"group": "",
"groupIndex": 0,
"text": "0.0.1",
"textType": "literal",
"text": "appVersion",
"textType": "expression",
"longMode": "WRAP",
"recolor": false
"recolor": false,
"previewValue": "0.0.1"
}
],
"widgetFlags": "CLICK_FOCUSABLE|GESTURE_BUBBLE|PRESS_LOCK|SCROLL_CHAIN_HOR|SCROLL_CHAIN_VER|SCROLL_ELASTIC|SCROLL_MOMENTUM|SCROLL_WITH_ARROW|SNAPPABLE",

View File

@ -1,6 +1,17 @@
package native
import "github.com/jetkvm/kvm/internal/logging"
import (
"github.com/jetkvm/kvm/internal/logging"
"github.com/rs/zerolog"
)
var nativeLogger = logging.GetSubsystemLogger("native")
var displayLogger = logging.GetSubsystemLogger("display")
type nativeLogMessage struct {
Level zerolog.Level
Message string
File string
FuncName string
Line int
}

View File

@ -51,111 +51,17 @@ func NewNative(opts NativeOptions) *Native {
}
func (n *Native) Start() {
go n.StartNativeVideo()
go n.HandleVideoChan()
// set up singleton
setInstance(n)
setUpNativeHandlers()
// start the native video
go n.handleLogChan()
go n.handleVideoStateChan()
go n.handleVideoFrameChan()
n.initUI()
go n.tickUI()
close(n.ready)
}
func (n *Native) HandleVideoChan() {
lastFrame := time.Now()
for {
frame := <-jkVideoChan
now := time.Now()
sinceLastFrame := now.Sub(lastFrame)
lastFrame = now
n.onVideoFrameReceived(frame, sinceLastFrame)
}
}
// func handleCtrlClient(conn net.Conn) {
// defer conn.Close()
// scopedLogger := nativeLogger.With().
// Str("addr", conn.RemoteAddr().String()).
// Str("type", "ctrl").
// Logger()
// scopedLogger.Info().Msg("native ctrl socket client connected")
// if ctrlSocketConn != nil {
// scopedLogger.Debug().Msg("closing existing native socket connection")
// ctrlSocketConn.Close()
// }
// ctrlSocketConn = conn
// // Restore HDMI EDID if applicable
// go restoreHdmiEdid()
// readBuf := make([]byte, 4096)
// for {
// n, err := conn.Read(readBuf)
// if err != nil {
// scopedLogger.Warn().Err(err).Msg("error reading from ctrl sock")
// break
// }
// readMsg := string(readBuf[:n])
// ctrlResp := CtrlResponse{}
// err = json.Unmarshal([]byte(readMsg), &ctrlResp)
// if err != nil {
// scopedLogger.Warn().Err(err).Str("data", readMsg).Msg("error parsing ctrl sock msg")
// continue
// }
// scopedLogger.Trace().Interface("data", ctrlResp).Msg("ctrl sock msg")
// if ctrlResp.Seq != 0 {
// responseChan, ok := ongoingRequests[ctrlResp.Seq]
// if ok {
// responseChan <- &ctrlResp
// }
// }
// switch ctrlResp.Event {
// case "video_input_state":
// HandleVideoStateMessage(ctrlResp)
// }
// }
// scopedLogger.Debug().Msg("ctrl sock disconnected")
// }
// func handleVideoClient(conn net.Conn) {
// defer conn.Close()
// scopedLogger := nativeLogger.With().
// Str("addr", conn.RemoteAddr().String()).
// Str("type", "video").
// Logger()
// scopedLogger.Info().Msg("native video socket client connected")
// inboundPacket := make([]byte, maxFrameSize)
// lastFrame := time.Now()
// for {
// n, err := conn.Read(inboundPacket)
// if err != nil {
// scopedLogger.Warn().Err(err).Msg("error during read")
// return
// }
// now := time.Now()
// sinceLastFrame := now.Sub(lastFrame)
// lastFrame = now
// if currentSession != nil {
// err := currentSession.VideoTrack.WriteSample(media.Sample{Data: inboundPacket[:n], Duration: sinceLastFrame})
// if err != nil {
// scopedLogger.Warn().Err(err).Msg("error writing sample")
// }
// }
// }
// }
// // Restore the HDMI EDID value from the config.
// // Called after successful connection to jetkvm_native.
// func restoreHdmiEdid() {
// if config.EdidString != "" {
// nativeLogger.Info().Str("edid", config.EdidString).Msg("Restoring HDMI EDID")
// _, err := CallCtrlAction("set_edid", map[string]interface{}{"edid": config.EdidString})
// if err != nil {
// nativeLogger.Warn().Err(err).Msg("Failed to restore HDMI EDID")
// }
// }
// }

View File

@ -1,7 +1,5 @@
package native
import "fmt"
type VideoState struct {
Ready bool `json:"ready"`
Error string `json:"error,omitempty"` //no_signal, no_lock, out_of_range
@ -10,7 +8,18 @@ type VideoState struct {
FramePerSecond float64 `json:"fps"`
}
func (n *Native) handleVideoStateMessage(state VideoState) {
nativeLogger.Info().Msg("video state handler")
nativeLogger.Info().Msg(fmt.Sprintf("state: %+v", state))
func (n *Native) VideoSetQualityFactor(factor float64) error {
return videoSetStreamQualityFactor(factor)
}
func (n *Native) VideoGetQualityFactor() (float64, error) {
return videoGetStreamQualityFactor()
}
func (n *Native) VideoSetEDID(edid string) error {
return videoSetEDID(edid)
}
func (n *Native) VideoGetEDID() (string, error) {
return videoGetEDID()
}

View File

@ -200,7 +200,7 @@ func rpcGetStreamQualityFactor() (float64, error) {
func rpcSetStreamQualityFactor(factor float64) error {
logger.Info().Float64("factor", factor).Msg("Setting stream quality factor")
err := nativeInstance.SetStreamQualityFactor(factor)
err := nativeInstance.VideoSetQualityFactor(factor)
if err != nil {
return err
}
@ -222,7 +222,7 @@ func rpcSetAutoUpdateState(enabled bool) (bool, error) {
}
func rpcGetEDID() (string, error) {
resp, err := nativeInstance.GetEDID()
resp, err := nativeInstance.VideoGetEDID()
if err != nil {
return "", err
}
@ -236,7 +236,7 @@ func rpcSetEDID(edid string) error {
} else {
logger.Info().Str("edid", edid).Msg("Setting EDID")
}
err := nativeInstance.SetEDID(edid)
err := nativeInstance.VideoSetEDID(edid)
if err != nil {
return err
}
@ -287,7 +287,7 @@ func rpcTryUpdate() error {
func rpcSetDisplayRotation(params DisplayRotationSettings) error {
var err error
_, err = nativeInstance.DispSetRotation(params.Rotation)
_, err = nativeInstance.DisplaySetRotation(params.Rotation)
if err == nil {
config.DisplayRotation = params.Rotation
if err := SaveConfig(); err != nil {