Skip to content

Commit e0f00cd

Browse files
committed
Fixed #290: improved blank diagnostics
1 parent 7a1d481 commit e0f00cd

File tree

9 files changed

+102
-33
lines changed

9 files changed

+102
-33
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
|----------|---------------|-------------------|
1212
| Multithreaded JPEG encoding |||
1313
| Hardware image encoding<br>on Raspberry Pi |||
14-
| Behavior when the device<br>is disconnected while streaming | ✔ Shows a black screen<br>with ```NO SIGNAL``` on it<br>until reconnected | ✘ Stops the streaming <sup>1</sup> |
14+
| Behavior when the device<br>is disconnected while streaming | ✔ Shows a black screen<br>with ```NO LIVE VIDEO``` on it<br>until reconnected | ✘ Stops the streaming <sup>1</sup> |
1515
| [DV-timings](https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/dv-timings.html) support -<br>the ability to change resolution<br>on the fly by source signal || ☹ Partially yes <sup>1</sup> |
1616
| Option to skip frames when streaming<br>static images by HTTP to save the traffic | ✔ <sup>2</sup> ||
1717
| Streaming via UNIX domain socket |||

src/libs/capture.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "threading.h"
4949
#include "frame.h"
5050
#include "xioctl.h"
51+
#include "tc358743.h"
5152

5253

5354
static const struct {
@@ -200,11 +201,11 @@ int us_capture_open(us_capture_s *cap) {
200201
}
201202
}
202203
_LOG_DEBUG("Probing DV-timings or QuerySTD ...");
203-
if (_capture_open_dv_timings(cap, false) < 0) {
204-
US_ONCE_FOR(run->open_error_once, __LINE__, {
205-
_LOG_ERROR("No signal from source");
206-
});
207-
goto error_no_signal;
204+
switch (_capture_open_dv_timings(cap, false)) {
205+
case 0: break;
206+
case US_ERROR_NO_SIGNAL: goto error_no_signal;
207+
case US_ERROR_NO_SYNC: goto error_no_sync;
208+
default: goto error;
208209
}
209210
}
210211

@@ -222,6 +223,15 @@ int us_capture_open(us_capture_s *cap) {
222223
if (_capture_open_format(cap, true) < 0) {
223224
goto error;
224225
}
226+
if (cap->dv_timings && cap->persistent) {
227+
struct v4l2_control ctl = {.id = TC358743_CID_LANES_ENOUGH};
228+
if (!us_xioctl(run->fd, VIDIOC_G_CTRL, &ctl)) {
229+
if (!ctl.value) {
230+
_LOG_ERROR("Not enough lanes, hardware can't handle this signal");
231+
goto error_no_lanes;
232+
}
233+
}
234+
}
225235
_capture_open_hw_fps(cap);
226236
_capture_open_jpeg_quality(cap);
227237
if (_capture_open_io_method(cap) < 0) {
@@ -259,8 +269,18 @@ int us_capture_open(us_capture_s *cap) {
259269
return US_ERROR_NO_CABLE;
260270

261271
error_no_signal:
272+
US_ONCE_FOR(run->open_error_once, __LINE__, { _LOG_ERROR("No signal from source"); });
262273
us_capture_close(cap);
263-
return US_ERROR_NO_DATA;
274+
return US_ERROR_NO_SIGNAL;
275+
276+
error_no_sync:
277+
US_ONCE_FOR(run->open_error_once, __LINE__, { _LOG_ERROR("No sync on signal"); });
278+
us_capture_close(cap);
279+
return US_ERROR_NO_SYNC;
280+
281+
error_no_lanes:
282+
us_capture_close(cap);
283+
return US_ERROR_NO_LANES;
264284

265285
error:
266286
run->open_error_once = 0;
@@ -630,6 +650,10 @@ static int _capture_open_dv_timings(us_capture_s *cap, bool apply) {
630650
// TC358743 errors here (see in the kernel: drivers/media/i2c/tc358743.c):
631651
// - ENOLINK: No valid signal (SYS_STATUS & MASK_S_TMDS)
632652
// - ENOLCK: No sync on signal (SYS_STATUS & MASK_S_SYNC)
653+
switch (errno) {
654+
case ENOLINK: return US_ERROR_NO_SIGNAL;
655+
case ENOLCK: return US_ERROR_NO_SYNC;
656+
}
633657
dv_errno = errno;
634658
goto querystd;
635659
} else if (!apply) {

src/libs/drm/drm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_capture_s *ca
378378
DRAW_MSG("=== PiKVM ===\n \n< UNSUPPORTED CAPTURE FORMAT >");
379379
break;
380380
case US_DRM_STUB_NO_SIGNAL:
381-
DRAW_MSG("=== PiKVM ===\n \n< NO SIGNAL >");
381+
DRAW_MSG("=== PiKVM ===\n \n< NO LIVE VIDEO >");
382382
break;
383383
case US_DRM_STUB_BUSY:
384384
DRAW_MSG("=== PiKVM ===\n \n< ONLINE IS ACTIVE >");

src/libs/errors.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@
2525
#define US_ERROR_COMMON -1
2626
#define US_ERROR_NO_DEVICE -2
2727
#define US_ERROR_NO_CABLE -3
28-
#define US_ERROR_NO_DATA -4
28+
#define US_ERROR_NO_SIGNAL -4
29+
#define US_ERROR_NO_SYNC -5
30+
#define US_ERROR_NO_LANES -6
31+
#define US_ERROR_NO_DATA -7

src/libs/tc358743.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,6 @@
3333
#include "xioctl.h"
3434

3535

36-
#ifndef V4L2_CID_USER_TC358743_BASE
37-
# define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080)
38-
#endif
39-
#ifndef TC358743_CID_AUDIO_PRESENT
40-
# define TC358743_CID_AUDIO_PRESENT (V4L2_CID_USER_TC358743_BASE + 1)
41-
#endif
42-
#ifndef TC358743_CID_AUDIO_SAMPLING_RATE
43-
# define TC358743_CID_AUDIO_SAMPLING_RATE (V4L2_CID_USER_TC358743_BASE + 0)
44-
#endif
45-
46-
4736
int us_tc358743_xioctl_get_audio_hz(int fd, uint *audio_hz) {
4837
*audio_hz = 0;
4938

src/libs/tc358743.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,26 @@
2222

2323
#pragma once
2424

25+
#include <linux/v4l2-controls.h>
26+
2527
#include "types.h"
2628

2729

30+
#ifndef V4L2_CID_USER_TC358743_BASE
31+
# define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080)
32+
#endif
33+
34+
#ifndef TC358743_CID_AUDIO_SAMPLING_RATE
35+
# define TC358743_CID_AUDIO_SAMPLING_RATE (V4L2_CID_USER_TC358743_BASE + 0)
36+
#endif
37+
38+
#ifndef TC358743_CID_AUDIO_PRESENT
39+
# define TC358743_CID_AUDIO_PRESENT (V4L2_CID_USER_TC358743_BASE + 1)
40+
#endif
41+
42+
#ifndef TC358743_CID_LANES_ENOUGH
43+
# define TC358743_CID_LANES_ENOUGH (V4L2_CID_USER_TC358743_BASE + 2)
44+
#endif
45+
46+
2847
int us_tc358743_xioctl_get_audio_hz(int fd, uint *audio_hz);

src/ustreamer/blank.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ us_blank_s *us_blank_init(void) {
3636
blank->ft = us_frametext_init();
3737
blank->raw = blank->ft->frame;
3838
blank->jpeg = us_frame_init();
39-
us_blank_draw(blank, "< NO SIGNAL >", 640, 480);
39+
us_blank_draw(blank, "< NO LIVE VIDEO >", 640, 480);
4040
return blank;
4141
}
4242

src/ustreamer/http/server.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ static void _http_send_snapshot(us_server_s *server) {
880880
if (!captured_meta.online) {
881881
if (blank == NULL) {
882882
blank = us_blank_init();
883-
us_blank_draw(blank, "< NO SIGNAL >", captured_meta.width, captured_meta.height);
883+
us_blank_draw(blank, "< NO LIVE VIDEO >", captured_meta.width, captured_meta.height);
884884
}
885885
frame = blank->jpeg;
886886
}

src/ustreamer/stream.c

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ us_stream_s *us_stream_init(us_capture_s *cap, us_encoder_s *enc) {
129129

130130
void us_stream_update_blank(us_stream_s *stream, const us_capture_s *cap) {
131131
us_stream_runtime_s *const run = stream->run;
132-
us_blank_draw(run->blank, "< NO SIGNAL >", cap->width, cap->height);
132+
us_blank_draw(run->blank, "< NO LIVE VIDEO >", cap->width, cap->height);
133133
us_fpsi_frame_to_meta(run->blank->raw, &run->notify_meta); // Initial "unchanged" meta
134134
_stream_update_captured_fpsi(stream, run->blank->raw, false);
135135
}
@@ -529,7 +529,7 @@ static int _stream_init_loop(us_stream_s *stream) {
529529

530530
int once = 0;
531531
while (!atomic_load(&stream->run->stop)) {
532-
char *blank_reason = "< NO SIGNAL >";
532+
char *blank_reason = "< NO LIVE VIDEO >";
533533

534534
# ifdef WITH_GPIO
535535
us_gpio_set_stream_online(false);
@@ -556,24 +556,58 @@ static int _stream_init_loop(us_stream_s *stream) {
556556
switch (us_capture_open(stream->cap)) {
557557
case 0: break;
558558
case US_ERROR_NO_DEVICE:
559-
blank_reason = "< NO CAPTURE DEVICE >";
560-
goto known_error;
559+
blank_reason = (
560+
"< NO CAPTURE DEVICE >\n \n"
561+
" Possible reasons: \n \n"
562+
" - Device unplugged \n \n"
563+
" - Bad config \n \n"
564+
" - Malfunction "
565+
);
566+
goto silent_error;
561567
case US_ERROR_NO_CABLE:
562-
blank_reason = "< NO VIDEO SOURCE >";
563-
goto known_error;
564-
case US_ERROR_NO_DATA:
565-
goto known_error;
568+
blank_reason = (
569+
"< NO VIDEO SOURCE >\n \n"
570+
" Possible reasons: \n \n"
571+
" - Source is off \n \n"
572+
" - Cable problems "
573+
);
574+
goto silent_error;
575+
case US_ERROR_NO_SIGNAL:
576+
blank_reason = (
577+
"< NO SIGNAL DETECTED >\n \n"
578+
" Possible reasons: \n \n"
579+
" - Video suspended \n \n"
580+
" - Cable problems "
581+
);
582+
goto silent_error;
583+
case US_ERROR_NO_SYNC:
584+
blank_reason = (
585+
"< NO SYNC WITH SIGNAL >\n \n"
586+
" Possible reasons: \n \n"
587+
" - Source is crazy \n \n"
588+
" - Cable problems "
589+
);
590+
goto silent_error;
591+
case US_ERROR_NO_LANES:
592+
blank_reason = (
593+
"< UNSUPPORTED SIGNAL TIMINGS >\n \n"
594+
" Possible reasons: \n \n"
595+
" - Too high frequency \n \n"
596+
" - Source ignores EDID \n \n"
597+
" - Invalid EDID "
598+
);
599+
goto verbose_error;
566600
default:
567-
goto unknown_error;
601+
goto verbose_error;
568602
}
569603
us_encoder_open(stream->enc, stream->cap);
570604
return 0;
571605

572-
known_error:
606+
silent_error:
573607
US_ONCE({ US_LOG_INFO("Waiting for the capture device ..."); });
574608
goto offline_and_retry;
575609

576-
unknown_error:
610+
verbose_error:
577611
once = 0;
578612
goto offline_and_retry;
579613

0 commit comments

Comments
 (0)