mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-10 09:33:43 +00:00
Issue #9: --last-as-blank accept timeout or 0
This commit is contained in:
@@ -108,6 +108,7 @@ struct http_server_t *http_server_init(struct stream_t *stream) {
|
|||||||
server->passwd = "";
|
server->passwd = "";
|
||||||
server->static_path = "";
|
server->static_path = "";
|
||||||
server->timeout = 10;
|
server->timeout = 10;
|
||||||
|
server->last_as_blank = -1;
|
||||||
server->run = run;
|
server->run = run;
|
||||||
|
|
||||||
assert(!evthread_use_pthreads());
|
assert(!evthread_use_pthreads());
|
||||||
@@ -169,7 +170,14 @@ int http_server_listen(struct http_server_t *server) {
|
|||||||
|
|
||||||
server->run->drop_same_frames_blank = max_u(server->drop_same_frames, server->run->drop_same_frames_blank);
|
server->run->drop_same_frames_blank = max_u(server->drop_same_frames, server->run->drop_same_frames_blank);
|
||||||
server->run->blank = blank_picture_init(server->blank_path);
|
server->run->blank = blank_picture_init(server->blank_path);
|
||||||
_expose_blank_picture(server);
|
|
||||||
|
# define EXPOSED(_next) server->run->exposed->_next
|
||||||
|
// See _expose_blank_picture()
|
||||||
|
picture_copy(server->run->blank, EXPOSED(picture));
|
||||||
|
EXPOSED(expose_begin_time) = get_now_monotonic();
|
||||||
|
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
|
||||||
|
EXPOSED(expose_end_time) = EXPOSED(expose_begin_time);
|
||||||
|
# undef EXPOSED
|
||||||
|
|
||||||
{
|
{
|
||||||
struct timeval refresh_interval;
|
struct timeval refresh_interval;
|
||||||
@@ -887,20 +895,39 @@ static bool _expose_new_picture_unsafe(struct http_server_t *server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool _expose_blank_picture(struct http_server_t *server) {
|
static bool _expose_blank_picture(struct http_server_t *server) {
|
||||||
# define EXPOSED(_next) server->run->exposed->_next
|
# define EXPOSED(_next) server->run->exposed->_next
|
||||||
|
|
||||||
EXPOSED(expose_begin_time) = get_now_monotonic();
|
EXPOSED(expose_begin_time) = get_now_monotonic();
|
||||||
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
|
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
|
||||||
|
|
||||||
if (EXPOSED(online) || EXPOSED(picture->used) == 0) {
|
# define EXPOSE_BLANK picture_copy(server->run->blank, EXPOSED(picture))
|
||||||
if (!(server->last_as_blank && EXPOSED(picture->used) > 0)) {
|
|
||||||
picture_copy(server->run->blank, EXPOSED(picture));
|
if (EXPOSED(online)) { // Если переходим из online в offline
|
||||||
|
if (server->last_as_blank < 0) { // Если last_as_blank выключено, просто покажем картинку
|
||||||
|
LOG_INFO("HTTP: changed picture to BLANK");
|
||||||
|
EXPOSE_BLANK;
|
||||||
|
} else if (server->last_as_blank > 0) { // Если нужен таймер - запустим
|
||||||
|
LOG_INFO("HTTP: freezing last alive frame for %d seconds", server->last_as_blank);
|
||||||
|
EXPOSED(last_as_blank_time) = get_now_monotonic();
|
||||||
|
} else { // last_as_blank == 0 - показываем последний фрейм вечно
|
||||||
|
LOG_INFO("HTTP: freezing last alive frame forever");
|
||||||
}
|
}
|
||||||
EXPOSED(captured_fps) = 0;
|
|
||||||
EXPOSED(online) = false;
|
|
||||||
goto updated;
|
goto updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( // Если уже оффлайн, включена фича last_as_blank с таймером и он запущен
|
||||||
|
server->last_as_blank > 0
|
||||||
|
&& EXPOSED(last_as_blank_time) > 0
|
||||||
|
&& EXPOSED(last_as_blank_time) + server->last_as_blank < EXPOSED(expose_begin_time)
|
||||||
|
) {
|
||||||
|
LOG_INFO("HTTP: changed last alive frame to BLANK");
|
||||||
|
EXPOSE_BLANK;
|
||||||
|
EXPOSED(last_as_blank_time) = 0; // Останавливаем таймер
|
||||||
|
goto updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
# undef EXPOSE_BLANK
|
||||||
|
|
||||||
if (EXPOSED(dropped) < server->run->drop_same_frames_blank) {
|
if (EXPOSED(dropped) < server->run->drop_same_frames_blank) {
|
||||||
LOG_PERF("HTTP: dropped same frame (BLANK) number %u", EXPOSED(dropped));
|
LOG_PERF("HTTP: dropped same frame (BLANK) number %u", EXPOSED(dropped));
|
||||||
EXPOSED(dropped) += 1;
|
EXPOSED(dropped) += 1;
|
||||||
@@ -909,6 +936,8 @@ static bool _expose_blank_picture(struct http_server_t *server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updated:
|
updated:
|
||||||
|
EXPOSED(captured_fps) = 0;
|
||||||
|
EXPOSED(online) = false;
|
||||||
EXPOSED(dropped) = 0;
|
EXPOSED(dropped) = 0;
|
||||||
EXPOSED(expose_end_time) = get_now_monotonic();
|
EXPOSED(expose_end_time) = get_now_monotonic();
|
||||||
return true; // Updated
|
return true; // Updated
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ struct exposed_t {
|
|||||||
long double expose_begin_time;
|
long double expose_begin_time;
|
||||||
long double expose_cmp_time;
|
long double expose_cmp_time;
|
||||||
long double expose_end_time;
|
long double expose_end_time;
|
||||||
|
long double last_as_blank_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct http_server_runtime_t {
|
struct http_server_runtime_t {
|
||||||
@@ -96,7 +97,7 @@ struct http_server_t {
|
|||||||
char *static_path;
|
char *static_path;
|
||||||
|
|
||||||
char *blank_path;
|
char *blank_path;
|
||||||
bool last_as_blank;
|
int last_as_blank;
|
||||||
unsigned drop_same_frames;
|
unsigned drop_same_frames;
|
||||||
bool slowdown;
|
bool slowdown;
|
||||||
unsigned fake_width;
|
unsigned fake_width;
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ static const struct option _LONG_OPTS[] = {
|
|||||||
{"passwd", required_argument, NULL, _O_PASSWD},
|
{"passwd", required_argument, NULL, _O_PASSWD},
|
||||||
{"static", required_argument, NULL, _O_STATIC},
|
{"static", required_argument, NULL, _O_STATIC},
|
||||||
{"blank", required_argument, NULL, _O_BLANK},
|
{"blank", required_argument, NULL, _O_BLANK},
|
||||||
{"last-as-blank", no_argument, NULL, _O_LAST_AS_BLANK},
|
{"last-as-blank", required_argument, NULL, _O_LAST_AS_BLANK},
|
||||||
{"drop-same-frames", required_argument, NULL, _O_DROP_SAME_FRAMES},
|
{"drop-same-frames", required_argument, NULL, _O_DROP_SAME_FRAMES},
|
||||||
{"slowdown", no_argument, NULL, _O_SLOWDOWN},
|
{"slowdown", no_argument, NULL, _O_SLOWDOWN},
|
||||||
{"fake-resolution", required_argument, NULL, _O_FAKE_RESOLUTION},
|
{"fake-resolution", required_argument, NULL, _O_FAKE_RESOLUTION},
|
||||||
@@ -319,7 +319,7 @@ int parse_options(int argc, char *argv[], struct device_t *dev, struct encoder_t
|
|||||||
case _O_PASSWD: OPT_SET(server->passwd, optarg);
|
case _O_PASSWD: OPT_SET(server->passwd, optarg);
|
||||||
case _O_STATIC: OPT_SET(server->static_path, optarg);
|
case _O_STATIC: OPT_SET(server->static_path, optarg);
|
||||||
case _O_BLANK: OPT_SET(server->blank_path, optarg);
|
case _O_BLANK: OPT_SET(server->blank_path, optarg);
|
||||||
case _O_LAST_AS_BLANK: OPT_SET(server->last_as_blank, true);
|
case _O_LAST_AS_BLANK: OPT_NUMBER("--last-as-blank", server->last_as_blank, 0, 86400, 0);
|
||||||
case _O_DROP_SAME_FRAMES: OPT_NUMBER("--drop-same-frames", server->drop_same_frames, 0, VIDEO_MAX_FPS, 0);
|
case _O_DROP_SAME_FRAMES: OPT_NUMBER("--drop-same-frames", server->drop_same_frames, 0, VIDEO_MAX_FPS, 0);
|
||||||
case _O_SLOWDOWN: OPT_SET(server->slowdown, true);
|
case _O_SLOWDOWN: OPT_SET(server->slowdown, true);
|
||||||
case _O_FAKE_RESOLUTION: OPT_RESOLUTION("--fake-resolution", server->fake_width, server->fake_height, false);
|
case _O_FAKE_RESOLUTION: OPT_RESOLUTION("--fake-resolution", server->fake_width, server->fake_height, false);
|
||||||
@@ -517,7 +517,8 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
|
|||||||
printf(" Symlinks are not supported for security reasons. Default: disabled.\n\n");
|
printf(" Symlinks are not supported for security reasons. Default: disabled.\n\n");
|
||||||
printf(" -k|--blank <path> ────────── Path to JPEG file that will be shown when the device is disconnected\n");
|
printf(" -k|--blank <path> ────────── Path to JPEG file that will be shown when the device is disconnected\n");
|
||||||
printf(" during the streaming. Default: black screen 640x480 with 'NO SIGNAL'.\n\n");
|
printf(" during the streaming. Default: black screen 640x480 with 'NO SIGNAL'.\n\n");
|
||||||
printf(" -K|--last-as-blank ───────── Show the last frame received from the camera after it was disconnected.\n");
|
printf(" -K|--last-as-blank <sec> ─── Show the last frame received from the camera after it was disconnected,\n");
|
||||||
|
printf(" but no more than specified time (or endlessly if 0 is specified).\n");
|
||||||
printf(" If the device has not yet been online, display 'NO SIGNAL' or the image\n");
|
printf(" If the device has not yet been online, display 'NO SIGNAL' or the image\n");
|
||||||
printf(" specified by option --blank. Default: disabled.\n\n");
|
printf(" specified by option --blank. Default: disabled.\n\n");
|
||||||
printf(" -e|--drop-same-frames <N> ── Don't send identical frames to clients, but no more than specified number.\n");
|
printf(" -e|--drop-same-frames <N> ── Don't send identical frames to clients, but no more than specified number.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user