mirror of https://github.com/jetkvm/kvm.git
211 lines
7.4 KiB
Diff
211 lines
7.4 KiB
Diff
diff --git a/internal/native/cgo/video.c b/internal/native/cgo/video.c
|
|
index 2a4a034..760621a 100644
|
|
--- a/internal/native/cgo/video.c
|
|
+++ b/internal/native/cgo/video.c
|
|
@@ -354,6 +354,10 @@ bool detected_signal = false, streaming_flag = false, streaming_stopped = true;
|
|
pthread_t *streaming_thread = NULL;
|
|
pthread_mutex_t streaming_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
+// Diagnostic tracking for validation
|
|
+static uint64_t last_close_time = 0;
|
|
+static int consecutive_failures = 0;
|
|
+
|
|
bool get_streaming_flag()
|
|
{
|
|
log_info("getting streaming flag");
|
|
@@ -395,6 +399,12 @@ void *run_video_stream(void *arg)
|
|
continue;
|
|
}
|
|
|
|
+ // Log attempt to open with timing info
|
|
+ RK_U64 time_since_close = last_close_time > 0 ? (get_us() - last_close_time) : 0;
|
|
+ log_info("[DIAG] Attempting to open %s (time_since_last_close=%llu us)",
|
|
+ VIDEO_DEV, time_since_close);
|
|
+
|
|
+ RK_U64 open_start_time = get_us();
|
|
int video_dev_fd = open(VIDEO_DEV, O_RDWR);
|
|
if (video_dev_fd < 0)
|
|
{
|
|
@@ -402,7 +412,9 @@ void *run_video_stream(void *arg)
|
|
usleep(1000000);
|
|
continue;
|
|
}
|
|
- log_info("opened video capture device %s", VIDEO_DEV);
|
|
+ RK_U64 open_end_time = get_us();
|
|
+ log_info("[DIAG] opened video capture device %s in %llu us",
|
|
+ VIDEO_DEV, open_end_time - open_start_time);
|
|
|
|
uint32_t width = detected_width;
|
|
uint32_t height = detected_height;
|
|
@@ -414,14 +426,45 @@ void *run_video_stream(void *arg)
|
|
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUYV;
|
|
fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
|
|
|
|
+ // Probe device state before attempting format set
|
|
+ struct v4l2_format query_fmt;
|
|
+ memset(&query_fmt, 0, sizeof(query_fmt));
|
|
+ query_fmt.type = type;
|
|
+ int query_ret = ioctl(video_dev_fd, VIDIOC_G_FMT, &query_fmt);
|
|
+ log_info("[DIAG] VIDIOC_G_FMT probe: ret=%d, errno=%d (%s)",
|
|
+ query_ret, query_ret < 0 ? errno : 0,
|
|
+ query_ret < 0 ? strerror(errno) : "OK");
|
|
+
|
|
+ RK_U64 set_fmt_start_time = get_us();
|
|
+ log_info("[DIAG] Attempting VIDIOC_S_FMT: %ux%u, time_since_open=%llu us",
|
|
+ width, height, set_fmt_start_time - open_end_time);
|
|
+
|
|
if (ioctl(video_dev_fd, VIDIOC_S_FMT, &fmt) < 0)
|
|
{
|
|
- log_error("Set format fail: %s", strerror(errno));
|
|
+ RK_U64 failure_time = get_us();
|
|
+ int saved_errno = errno;
|
|
+ consecutive_failures++;
|
|
+
|
|
+ log_error("[DIAG] Set format fail: errno=%d (%s)", saved_errno, strerror(saved_errno));
|
|
+ log_error("[DIAG] Failure context: consecutive_failures=%d, time_since_open=%llu us, "
|
|
+ "time_since_last_close=%llu us, resolution=%ux%u, streaming_flag=%d",
|
|
+ consecutive_failures,
|
|
+ failure_time - open_end_time,
|
|
+ last_close_time > 0 ? (open_start_time - last_close_time) : 0,
|
|
+ width, height,
|
|
+ streaming_flag);
|
|
+
|
|
usleep(100000); // Sleep for 100 milliseconds
|
|
close(video_dev_fd);
|
|
+ last_close_time = get_us();
|
|
+ log_info("[DIAG] Closed device after format failure at %llu us", last_close_time);
|
|
continue;
|
|
}
|
|
|
|
+ // Success - reset failure counter
|
|
+ log_info("[DIAG] VIDIOC_S_FMT succeeded (previous consecutive failures: %d)", consecutive_failures);
|
|
+ consecutive_failures = 0;
|
|
+
|
|
struct v4l2_buffer buf;
|
|
|
|
struct v4l2_requestbuffers req;
|
|
@@ -601,9 +644,46 @@ void *run_video_stream(void *arg)
|
|
}
|
|
cleanup:
|
|
log_info("cleaning up video capture device %s", VIDEO_DEV);
|
|
- if (ioctl(video_dev_fd, VIDIOC_STREAMOFF, &type) < 0)
|
|
+
|
|
+ RK_U64 streamoff_start = get_us();
|
|
+ log_info("[DIAG] Attempting VIDIOC_STREAMOFF");
|
|
+
|
|
+ int streamoff_ret = ioctl(video_dev_fd, VIDIOC_STREAMOFF, &type);
|
|
+ RK_U64 streamoff_end = get_us();
|
|
+
|
|
+ if (streamoff_ret < 0)
|
|
+ {
|
|
+ log_error("[DIAG] VIDIOC_STREAMOFF failed: errno=%d (%s), duration=%llu us",
|
|
+ errno, strerror(errno), streamoff_end - streamoff_start);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ log_info("[DIAG] VIDIOC_STREAMOFF succeeded in %llu us",
|
|
+ streamoff_end - streamoff_start);
|
|
+ }
|
|
+
|
|
+ // VALIDATION TEST: Explicitly free V4L2 buffer queue
|
|
+ struct v4l2_requestbuffers req_free;
|
|
+ memset(&req_free, 0, sizeof(req_free));
|
|
+ req_free.count = 0; // Tell driver to free all buffers
|
|
+ req_free.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
|
+ req_free.memory = V4L2_MEMORY_DMABUF;
|
|
+
|
|
+ RK_U64 reqbufs_start = get_us();
|
|
+ log_info("[DIAG] VALIDATION: Calling VIDIOC_REQBUFS(count=0) to free buffer queue");
|
|
+
|
|
+ int reqbufs_ret = ioctl(video_dev_fd, VIDIOC_REQBUFS, &req_free);
|
|
+ RK_U64 reqbufs_end = get_us();
|
|
+
|
|
+ if (reqbufs_ret < 0)
|
|
+ {
|
|
+ log_error("[DIAG] VALIDATION: REQBUFS(0) FAILED - errno=%d (%s), duration=%llu us",
|
|
+ errno, strerror(errno), reqbufs_end - reqbufs_start);
|
|
+ }
|
|
+ else
|
|
{
|
|
- log_error("VIDIOC_STREAMOFF failed: %s", strerror(errno));
|
|
+ log_info("[DIAG] VALIDATION: REQBUFS(0) SUCCEEDED - freed buffers in %llu us",
|
|
+ reqbufs_end - reqbufs_start);
|
|
}
|
|
|
|
venc_stop();
|
|
@@ -617,9 +697,13 @@ void *run_video_stream(void *arg)
|
|
}
|
|
|
|
log_info("closing video capture device %s", VIDEO_DEV);
|
|
+ RK_U64 close_start = get_us();
|
|
close(video_dev_fd);
|
|
+ last_close_time = get_us();
|
|
+ log_info("[DIAG] Device closed, took %llu us, timestamp=%llu",
|
|
+ last_close_time - close_start, last_close_time);
|
|
}
|
|
-
|
|
+
|
|
log_info("video stream thread exiting");
|
|
|
|
streaming_stopped = true;
|
|
@@ -648,7 +732,7 @@ void video_shutdown()
|
|
RK_MPI_MB_DestroyPool(memPool);
|
|
}
|
|
log_info("Destroyed memory pool");
|
|
-
|
|
+
|
|
pthread_mutex_destroy(&streaming_mutex);
|
|
log_info("Destroyed streaming mutex");
|
|
}
|
|
@@ -665,14 +749,14 @@ void video_start_streaming()
|
|
log_warn("video streaming already started");
|
|
return;
|
|
}
|
|
-
|
|
+
|
|
pthread_t *new_thread = malloc(sizeof(pthread_t));
|
|
if (new_thread == NULL)
|
|
{
|
|
log_error("Failed to allocate memory for streaming thread");
|
|
return;
|
|
}
|
|
-
|
|
+
|
|
set_streaming_flag(true);
|
|
int result = pthread_create(new_thread, NULL, run_video_stream, NULL);
|
|
if (result != 0)
|
|
@@ -682,7 +766,7 @@ void video_start_streaming()
|
|
free(new_thread);
|
|
return;
|
|
}
|
|
-
|
|
+
|
|
// Only set streaming_thread after successful creation
|
|
streaming_thread = new_thread;
|
|
}
|
|
@@ -693,7 +777,7 @@ void video_stop_streaming()
|
|
log_info("video streaming already stopped");
|
|
return;
|
|
}
|
|
-
|
|
+
|
|
log_info("stopping video streaming");
|
|
set_streaming_flag(false);
|
|
|
|
@@ -711,7 +795,7 @@ void video_stop_streaming()
|
|
free(streaming_thread);
|
|
streaming_thread = NULL;
|
|
|
|
- log_info("video streaming stopped");
|
|
+ log_info("video streaming stopped");
|
|
}
|
|
|
|
void video_restart_streaming()
|
|
@@ -818,4 +902,4 @@ void video_set_quality_factor(float factor)
|
|
|
|
float video_get_quality_factor() {
|
|
return quality_factor;
|
|
-}
|
|
\ No newline at end of file
|
|
+}
|