diff --git a/internal/native/cgo/ctrl.c b/internal/native/cgo/ctrl.c index ef5eb32a..62d2c8b9 100644 --- a/internal/native/cgo/ctrl.c +++ b/internal/native/cgo/ctrl.c @@ -59,6 +59,7 @@ const char *jetkvm_ui_event_code_to_name(int code) { void video_report_format(bool ready, const char *error, u_int16_t width, u_int16_t height, double frame_per_second) { + state.streaming = video_get_streaming_status(); state.ready = ready; state.error = error; state.width = width; @@ -69,6 +70,13 @@ void video_report_format(bool ready, const char *error, u_int16_t width, u_int16 } } +void video_send_format_report() { + state.streaming = video_get_streaming_status(); + if (video_state_handler != NULL) { + (*video_state_handler)(&state); + } +} + int video_send_frame(const uint8_t *frame, ssize_t len) { if (video_handler != NULL) { diff --git a/internal/native/cgo/ctrl.h b/internal/native/cgo/ctrl.h index 62009efc..59f9e4cd 100644 --- a/internal/native/cgo/ctrl.h +++ b/internal/native/cgo/ctrl.h @@ -8,6 +8,7 @@ typedef struct { bool ready; + uint8_t streaming; const char *error; u_int16_t width; u_int16_t height; @@ -65,6 +66,7 @@ char *jetkvm_video_log_status(); jetkvm_video_state_t *jetkvm_video_get_status(); void video_report_format(bool ready, const char *error, u_int16_t width, u_int16_t height, double frame_per_second); +void video_send_format_report(); int video_send_frame(const uint8_t *frame, ssize_t len); diff --git a/internal/native/cgo/video.c b/internal/native/cgo/video.c index d3c37310..e9d69440 100644 --- a/internal/native/cgo/video.c +++ b/internal/native/cgo/video.c @@ -654,6 +654,8 @@ void *run_video_stream(void *arg) set_streaming_stopped(true); + video_send_format_report(); + return NULL; } @@ -716,6 +718,8 @@ void video_start_streaming() // Only set streaming_thread after successful creation streaming_thread = new_thread; + + video_send_format_report(); } bool wait_for_streaming_stopped() @@ -751,6 +755,8 @@ void video_stop_streaming() streaming_thread = NULL; log_info("video streaming stopped"); + + video_send_format_report(); } uint8_t video_get_streaming_status() { diff --git a/internal/native/cgo_linux.go b/internal/native/cgo_linux.go index b020e745..dcd25e42 100644 --- a/internal/native/cgo_linux.go +++ b/internal/native/cgo_linux.go @@ -57,6 +57,7 @@ var ( func jetkvm_go_video_state_handler(state *C.jetkvm_video_state_t) { videoState := VideoState{ Ready: bool(state.ready), + Streaming: VideoStreamingStatus(state.streaming), Error: C.GoString(state.error), Width: int(state.width), Height: int(state.height), diff --git a/internal/native/chan.go b/internal/native/chan.go index 4162f260..cd6d07af 100644 --- a/internal/native/chan.go +++ b/internal/native/chan.go @@ -28,6 +28,7 @@ func (n *Native) handleVideoFrameChan() { func (n *Native) handleVideoStateChan() { for { state := <-videoStateChan + n.onVideoStateChange(state) } } diff --git a/internal/native/grpc_servermethods.go b/internal/native/grpc_servermethods.go index cc16dfd1..c1dea54f 100644 --- a/internal/native/grpc_servermethods.go +++ b/internal/native/grpc_servermethods.go @@ -70,9 +70,6 @@ func (s *grpcServer) VideoLogStatus(ctx context.Context, req *pb.Empty) (*pb.Vid } func (s *grpcServer) VideoStop(ctx context.Context, req *pb.Empty) (*pb.Empty, error) { - procPrefix = "jetkvm: [native]" - setProcTitle(lastProcTitle) - if err := s.native.VideoStop(); err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -80,9 +77,6 @@ func (s *grpcServer) VideoStop(ctx context.Context, req *pb.Empty) (*pb.Empty, e } func (s *grpcServer) VideoStart(ctx context.Context, req *pb.Empty) (*pb.Empty, error) { - procPrefix = "jetkvm: [native+video]" - setProcTitle(lastProcTitle) - if err := s.native.VideoStart(); err != nil { return nil, status.Error(codes.Internal, err.Error()) } diff --git a/internal/native/server.go b/internal/native/server.go index ae983159..7fa6c987 100644 --- a/internal/native/server.go +++ b/internal/native/server.go @@ -54,6 +54,23 @@ func monitorCrashSignal(ctx context.Context, logger *zerolog.Logger, nativeInsta } } +func updateProcessTitle(state *VideoState) { + if state == nil { + procPrefix = "jetkvm: [native]" + } else { + status := "active" + if !state.Ready { + status = "starting" + } else if state.Error != "" { + status = state.Error + } else { + status = fmt.Sprintf("%s,%dx%d,%.1ffps", state.Streaming.String(), state.Width, state.Height, state.FramePerSecond) + } + procPrefix = fmt.Sprintf("jetkvm: [native+video{%s}]", status) + } + setProcTitle(lastProcTitle) +} + // RunNativeProcess runs the native process mode func RunNativeProcess(binaryName string) { appCtx, appCtxCancel := context.WithCancel(context.Background()) @@ -82,6 +99,9 @@ func RunNativeProcess(binaryName string) { logger.Fatal().Err(err).Msg("failed to write frame to video stream socket") } } + nativeOptions.OnVideoStateChange = func(state VideoState) { + updateProcessTitle(&state) + } // Create native instance nativeInstance := NewNative(*nativeOptions) diff --git a/internal/native/video.go b/internal/native/video.go index b46f2b68..c360441b 100644 --- a/internal/native/video.go +++ b/internal/native/video.go @@ -15,11 +15,12 @@ var extraLockTimeout = 5 * time.Second // VideoState is the state of the video stream. type VideoState struct { - Ready bool `json:"ready"` - Error string `json:"error,omitempty"` //no_signal, no_lock, out_of_range - Width int `json:"width"` - Height int `json:"height"` - FramePerSecond float64 `json:"fps"` + Ready bool `json:"ready"` + Streaming VideoStreamingStatus `json:"streaming"` + Error string `json:"error,omitempty"` //no_signal, no_lock, out_of_range + Width int `json:"width"` + Height int `json:"height"` + FramePerSecond float64 `json:"fps"` } func isSleepModeSupported() bool {