mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-04-16 03:26:12 +00:00
refactoring
This commit is contained in:
@@ -72,6 +72,7 @@ us_drm_s *us_drm_init(void) {
|
|||||||
run->fd = -1;
|
run->fd = -1;
|
||||||
run->status_fd = -1;
|
run->status_fd = -1;
|
||||||
run->dpms_state = -1;
|
run->dpms_state = -1;
|
||||||
|
run->opened = -1;
|
||||||
run->has_vsync = true;
|
run->has_vsync = true;
|
||||||
run->exposing_dma_fd = -1;
|
run->exposing_dma_fd = -1;
|
||||||
run->ft = us_frametext_init();
|
run->ft = us_frametext_init();
|
||||||
@@ -82,6 +83,7 @@ us_drm_s *us_drm_init(void) {
|
|||||||
drm->path = "/dev/dri/by-path/platform-gpu-card";
|
drm->path = "/dev/dri/by-path/platform-gpu-card";
|
||||||
drm->port = "HDMI-A-2"; // OUT2 on PiKVM V4 Plus
|
drm->port = "HDMI-A-2"; // OUT2 on PiKVM V4 Plus
|
||||||
drm->timeout = 5;
|
drm->timeout = 5;
|
||||||
|
drm->blank_after = 5;
|
||||||
drm->run = run;
|
drm->run = run;
|
||||||
return drm;
|
return drm;
|
||||||
}
|
}
|
||||||
@@ -97,6 +99,8 @@ int us_drm_open(us_drm_s *drm, const us_capture_s *cap) {
|
|||||||
|
|
||||||
assert(run->fd < 0);
|
assert(run->fd < 0);
|
||||||
|
|
||||||
|
_LOG_INFO("Using passthrough: %s[%s]", drm->path, drm->port);
|
||||||
|
|
||||||
switch (_drm_check_status(drm)) {
|
switch (_drm_check_status(drm)) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
case US_ERROR_NO_DEVICE: goto unplugged;
|
case US_ERROR_NO_DEVICE: goto unplugged;
|
||||||
@@ -164,22 +168,24 @@ int us_drm_open(us_drm_s *drm, const us_capture_s *cap) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
run->opened_for_stub = (stub > 0);
|
_LOG_INFO("Opened for %s ...", (stub > 0 ? "STUB" : "DMA"));
|
||||||
run->exposing_dma_fd = -1;
|
run->exposing_dma_fd = -1;
|
||||||
run->unplugged_once = 0;
|
run->blank_at_ts = 0;
|
||||||
_LOG_INFO("Opened for %s ...", (run->opened_for_stub ? "STUB" : "DMA"));
|
run->opened = stub;
|
||||||
return stub;
|
run->once = 0;
|
||||||
|
return run->opened;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
us_drm_close(drm);
|
us_drm_close(drm);
|
||||||
return -1;
|
return run->opened; // -1 after us_drm_close()
|
||||||
|
|
||||||
unplugged:
|
unplugged:
|
||||||
US_ONCE_FOR(run->unplugged_once, __LINE__, {
|
US_ONCE_FOR(run->once, __LINE__, {
|
||||||
_LOG_ERROR("Display is not plugged");
|
_LOG_ERROR("Display is not plugged");
|
||||||
});
|
});
|
||||||
us_drm_close(drm);
|
us_drm_close(drm);
|
||||||
return US_ERROR_NO_DEVICE;
|
run->opened = US_ERROR_NO_DEVICE;
|
||||||
|
return run->opened;
|
||||||
}
|
}
|
||||||
|
|
||||||
void us_drm_close(us_drm_s *drm) {
|
void us_drm_close(us_drm_s *drm) {
|
||||||
@@ -233,6 +239,7 @@ void us_drm_close(us_drm_s *drm) {
|
|||||||
|
|
||||||
run->crtc_id = 0;
|
run->crtc_id = 0;
|
||||||
run->dpms_state = -1;
|
run->dpms_state = -1;
|
||||||
|
run->opened = -1;
|
||||||
run->has_vsync = true;
|
run->has_vsync = true;
|
||||||
run->stub_n_buf = 0;
|
run->stub_n_buf = 0;
|
||||||
|
|
||||||
@@ -241,6 +248,34 @@ void us_drm_close(us_drm_s *drm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int us_drm_ensure_no_signal(us_drm_s *drm) {
|
||||||
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
|
||||||
|
assert(run->fd >= 0);
|
||||||
|
assert(run->opened > 0);
|
||||||
|
|
||||||
|
const ldf now_ts = us_get_now_monotonic();
|
||||||
|
if (run->blank_at_ts == 0) {
|
||||||
|
run->blank_at_ts = now_ts + drm->blank_after;
|
||||||
|
}
|
||||||
|
const ldf saved_ts = run->blank_at_ts; // us_drm*() rewrites it to 0
|
||||||
|
|
||||||
|
int retval;
|
||||||
|
if (now_ts <= run->blank_at_ts) {
|
||||||
|
retval = us_drm_wait_for_vsync(drm);
|
||||||
|
if (retval == 0) {
|
||||||
|
retval = us_drm_expose_stub(drm, US_DRM_STUB_NO_SIGNAL, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
US_ONCE_FOR(run->once, __LINE__, {
|
||||||
|
_LOG_INFO("Turning off the display by timeout ...");
|
||||||
|
});
|
||||||
|
retval = us_drm_dpms_power_off(drm);
|
||||||
|
}
|
||||||
|
run->blank_at_ts = saved_ts;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
int us_drm_dpms_power_off(us_drm_s *drm) {
|
int us_drm_dpms_power_off(us_drm_s *drm) {
|
||||||
assert(drm->run->fd >= 0);
|
assert(drm->run->fd >= 0);
|
||||||
switch (_drm_check_status(drm)) {
|
switch (_drm_check_status(drm)) {
|
||||||
@@ -259,6 +294,7 @@ int us_drm_wait_for_vsync(us_drm_s *drm) {
|
|||||||
us_drm_runtime_s *const run = drm->run;
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
|
||||||
assert(run->fd >= 0);
|
assert(run->fd >= 0);
|
||||||
|
run->blank_at_ts = 0;
|
||||||
|
|
||||||
switch (_drm_check_status(drm)) {
|
switch (_drm_check_status(drm)) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
@@ -313,7 +349,8 @@ int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_capture_s *ca
|
|||||||
us_drm_runtime_s *const run = drm->run;
|
us_drm_runtime_s *const run = drm->run;
|
||||||
|
|
||||||
assert(run->fd >= 0);
|
assert(run->fd >= 0);
|
||||||
assert(run->opened_for_stub);
|
assert(run->opened > 0);
|
||||||
|
run->blank_at_ts = 0;
|
||||||
|
|
||||||
switch (_drm_check_status(drm)) {
|
switch (_drm_check_status(drm)) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
@@ -377,7 +414,8 @@ int us_drm_expose_dma(us_drm_s *drm, const us_capture_hwbuf_s *hw) {
|
|||||||
us_drm_buffer_s *const buf = &run->bufs[hw->buf.index];
|
us_drm_buffer_s *const buf = &run->bufs[hw->buf.index];
|
||||||
|
|
||||||
assert(run->fd >= 0);
|
assert(run->fd >= 0);
|
||||||
assert(!run->opened_for_stub);
|
assert(run->opened == 0);
|
||||||
|
run->blank_at_ts = 0;
|
||||||
|
|
||||||
switch (_drm_check_status(drm)) {
|
switch (_drm_check_status(drm)) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
|
|||||||
@@ -63,11 +63,14 @@ typedef struct {
|
|||||||
uint n_bufs;
|
uint n_bufs;
|
||||||
drmModeCrtc *saved_crtc;
|
drmModeCrtc *saved_crtc;
|
||||||
int dpms_state;
|
int dpms_state;
|
||||||
bool opened_for_stub;
|
int opened;
|
||||||
|
|
||||||
bool has_vsync;
|
bool has_vsync;
|
||||||
int exposing_dma_fd;
|
int exposing_dma_fd;
|
||||||
uint stub_n_buf;
|
uint stub_n_buf;
|
||||||
int unplugged_once;
|
ldf blank_at_ts;
|
||||||
|
|
||||||
|
int once;
|
||||||
us_frametext_s *ft;
|
us_frametext_s *ft;
|
||||||
} us_drm_runtime_s;
|
} us_drm_runtime_s;
|
||||||
|
|
||||||
@@ -75,6 +78,7 @@ typedef struct {
|
|||||||
char *path;
|
char *path;
|
||||||
char *port;
|
char *port;
|
||||||
uint timeout;
|
uint timeout;
|
||||||
|
uint blank_after;
|
||||||
|
|
||||||
us_drm_runtime_s *run;
|
us_drm_runtime_s *run;
|
||||||
} us_drm_s;
|
} us_drm_s;
|
||||||
@@ -90,3 +94,4 @@ int us_drm_dpms_power_off(us_drm_s *drm);
|
|||||||
int us_drm_wait_for_vsync(us_drm_s *drm);
|
int us_drm_wait_for_vsync(us_drm_s *drm);
|
||||||
int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_capture_s *cap);
|
int us_drm_expose_stub(us_drm_s *drm, us_drm_stub_e stub, const us_capture_s *cap);
|
||||||
int us_drm_expose_dma(us_drm_s *drm, const us_capture_hwbuf_s *hw);
|
int us_drm_expose_dma(us_drm_s *drm, const us_capture_hwbuf_s *hw);
|
||||||
|
int us_drm_ensure_no_signal(us_drm_s *drm);
|
||||||
|
|||||||
@@ -270,6 +270,9 @@ void us_options_destroy(us_options_s *options) {
|
|||||||
US_DELETE(options->jpeg_sink, us_memsink_destroy);
|
US_DELETE(options->jpeg_sink, us_memsink_destroy);
|
||||||
US_DELETE(options->raw_sink, us_memsink_destroy);
|
US_DELETE(options->raw_sink, us_memsink_destroy);
|
||||||
US_DELETE(options->h264_sink, us_memsink_destroy);
|
US_DELETE(options->h264_sink, us_memsink_destroy);
|
||||||
|
# ifdef WITH_V4P
|
||||||
|
US_DELETE(options->drm, us_drm_destroy);
|
||||||
|
# endif
|
||||||
|
|
||||||
for (unsigned index = 0; index < options->argc; ++index) {
|
for (unsigned index = 0; index < options->argc; ++index) {
|
||||||
free(options->argv_copy[index]);
|
free(options->argv_copy[index]);
|
||||||
@@ -463,7 +466,10 @@ int options_parse(us_options_s *options, us_capture_s *cap, us_encoder_s *enc, u
|
|||||||
case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg);
|
case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg);
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
case _O_V4P: OPT_SET(stream->v4p, true);
|
case _O_V4P:
|
||||||
|
options->drm = us_drm_init();
|
||||||
|
stream->drm = options->drm;
|
||||||
|
break;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
#include "../libs/memsink.h"
|
#include "../libs/memsink.h"
|
||||||
#include "../libs/options.h"
|
#include "../libs/options.h"
|
||||||
#include "../libs/capture.h"
|
#include "../libs/capture.h"
|
||||||
|
#ifdef WITH_V4P
|
||||||
|
# include "../libs/drm/drm.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "encoder.h"
|
#include "encoder.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
@@ -56,6 +59,9 @@ typedef struct {
|
|||||||
us_memsink_s *jpeg_sink;
|
us_memsink_s *jpeg_sink;
|
||||||
us_memsink_s *raw_sink;
|
us_memsink_s *raw_sink;
|
||||||
us_memsink_s *h264_sink;
|
us_memsink_s *h264_sink;
|
||||||
|
# ifdef WITH_V4P
|
||||||
|
us_drm_s *drm;
|
||||||
|
# endif
|
||||||
} us_options_s;
|
} us_options_s;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -138,14 +138,6 @@ void us_stream_loop(us_stream_s *stream) {
|
|||||||
run->h264 = us_h264_stream_init(stream->h264_sink, stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop);
|
run->h264 = us_h264_stream_init(stream->h264_sink, stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop);
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
|
||||||
if (stream->v4p) {
|
|
||||||
run->drm = us_drm_init();
|
|
||||||
run->drm_opened = -1;
|
|
||||||
US_LOG_INFO("Using passthrough: %s[%s]", run->drm->path, run->drm->port);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
while (!_stream_init_loop(stream)) {
|
while (!_stream_init_loop(stream)) {
|
||||||
atomic_bool threads_stop;
|
atomic_bool threads_stop;
|
||||||
atomic_init(&threads_stop, false);
|
atomic_init(&threads_stop, false);
|
||||||
@@ -177,7 +169,7 @@ void us_stream_loop(us_stream_s *stream) {
|
|||||||
CREATE_WORKER((run->h264 != NULL), h264_ctx, _h264_thread, cap->run->n_bufs);
|
CREATE_WORKER((run->h264 != NULL), h264_ctx, _h264_thread, cap->run->n_bufs);
|
||||||
CREATE_WORKER((stream->raw_sink != NULL), raw_ctx, _raw_thread, 2);
|
CREATE_WORKER((stream->raw_sink != NULL), raw_ctx, _raw_thread, 2);
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
CREATE_WORKER((run->drm != NULL), drm_ctx, _drm_thread, cap->run->n_bufs); // cppcheck-suppress assertWithSideEffect
|
CREATE_WORKER((stream->drm != NULL), drm_ctx, _drm_thread, cap->run->n_bufs); // cppcheck-suppress assertWithSideEffect
|
||||||
# endif
|
# endif
|
||||||
# undef CREATE_WORKER
|
# undef CREATE_WORKER
|
||||||
|
|
||||||
@@ -267,9 +259,6 @@ void us_stream_loop(us_stream_s *stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
|
||||||
US_DELETE(run->drm, us_drm_destroy);
|
|
||||||
# endif
|
|
||||||
US_DELETE(run->h264, us_h264_stream_destroy);
|
US_DELETE(run->h264, us_h264_stream_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,11 +442,10 @@ static void *_raw_thread(void *v_ctx) {
|
|||||||
static void *_drm_thread(void *v_ctx) {
|
static void *_drm_thread(void *v_ctx) {
|
||||||
US_THREAD_SETTLE("str_drm");
|
US_THREAD_SETTLE("str_drm");
|
||||||
_worker_context_s *ctx = v_ctx;
|
_worker_context_s *ctx = v_ctx;
|
||||||
us_stream_runtime_s *run = ctx->stream->run;
|
us_stream_s *stream = ctx->stream;
|
||||||
|
|
||||||
// Close previously opened DRM for a stub
|
// Close previously opened DRM for a stub
|
||||||
us_drm_close(run->drm);
|
us_drm_close(stream->drm);
|
||||||
run->drm_opened = -1;
|
|
||||||
|
|
||||||
us_capture_hwbuf_s *prev_hw = NULL;
|
us_capture_hwbuf_s *prev_hw = NULL;
|
||||||
while (!atomic_load(ctx->stop)) {
|
while (!atomic_load(ctx->stop)) {
|
||||||
@@ -472,10 +460,10 @@ static void *_drm_thread(void *v_ctx) {
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(run->drm_opened = us_drm_open(run->drm, ctx->stream->cap));
|
CHECK(us_drm_open(stream->drm, ctx->stream->cap));
|
||||||
|
|
||||||
while (!atomic_load(ctx->stop)) {
|
while (!atomic_load(ctx->stop)) {
|
||||||
CHECK(us_drm_wait_for_vsync(run->drm));
|
CHECK(us_drm_wait_for_vsync(stream->drm));
|
||||||
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
||||||
|
|
||||||
us_capture_hwbuf_s *hw = _get_latest_hw(ctx->queue);
|
us_capture_hwbuf_s *hw = _get_latest_hw(ctx->queue);
|
||||||
@@ -483,21 +471,20 @@ static void *_drm_thread(void *v_ctx) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run->drm_opened == 0) {
|
if (stream->drm->run->opened == 0) {
|
||||||
CHECK(us_drm_expose_dma(run->drm, hw));
|
CHECK(us_drm_expose_dma(stream->drm, hw));
|
||||||
prev_hw = hw;
|
prev_hw = hw;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(us_drm_expose_stub(run->drm, run->drm_opened, ctx->stream->cap));
|
CHECK(us_drm_expose_stub(stream->drm, stream->drm->run->opened, ctx->stream->cap));
|
||||||
us_capture_hwbuf_decref(hw);
|
us_capture_hwbuf_decref(hw);
|
||||||
|
|
||||||
SLOWDOWN;
|
SLOWDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
close:
|
close:
|
||||||
us_drm_close(run->drm);
|
us_drm_close(stream->drm);
|
||||||
run->drm_opened = -1;
|
|
||||||
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
||||||
SLOWDOWN;
|
SLOWDOWN;
|
||||||
|
|
||||||
@@ -536,7 +523,7 @@ static bool _stream_has_any_clients_cached(us_stream_s *stream) {
|
|||||||
|| (run->h264 != NULL && atomic_load(&run->h264->sink->has_clients))
|
|| (run->h264 != NULL && atomic_load(&run->h264->sink->has_clients))
|
||||||
|| (stream->raw_sink != NULL && atomic_load(&stream->raw_sink->has_clients))
|
|| (stream->raw_sink != NULL && atomic_load(&stream->raw_sink->has_clients))
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
|| (run->drm != NULL)
|
|| (stream->drm != NULL)
|
||||||
# endif
|
# endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -568,7 +555,7 @@ static int _stream_init_loop(us_stream_s *stream) {
|
|||||||
stream->enc->type == US_ENCODER_TYPE_M2M_VIDEO
|
stream->enc->type == US_ENCODER_TYPE_M2M_VIDEO
|
||||||
|| stream->enc->type == US_ENCODER_TYPE_M2M_IMAGE
|
|| stream->enc->type == US_ENCODER_TYPE_M2M_IMAGE
|
||||||
|| run->h264 != NULL
|
|| run->h264 != NULL
|
||||||
|| run->drm != NULL
|
|| stream->drm != NULL
|
||||||
);
|
);
|
||||||
switch (us_capture_open(stream->cap)) {
|
switch (us_capture_open(stream->cap)) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
@@ -618,37 +605,21 @@ static int _stream_init_loop(us_stream_s *stream) {
|
|||||||
|
|
||||||
#ifdef WITH_V4P
|
#ifdef WITH_V4P
|
||||||
static void _stream_drm_ensure_no_signal(us_stream_s *stream) {
|
static void _stream_drm_ensure_no_signal(us_stream_s *stream) {
|
||||||
us_stream_runtime_s *const run = stream->run;
|
if (stream->drm == NULL) {
|
||||||
|
|
||||||
if (run->drm == NULL) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (stream->drm->run->opened <= 0) {
|
||||||
# define CHECK(x_arg) if ((x_arg) < 0) { goto close; }
|
us_drm_close(stream->drm);
|
||||||
if (run->drm_opened <= 0) {
|
if (us_drm_open(stream->drm, NULL) < 0) {
|
||||||
us_drm_close(run->drm);
|
goto close;
|
||||||
run->drm_blank_at_ts = 0;
|
}
|
||||||
CHECK(run->drm_opened = us_drm_open(run->drm, NULL));
|
|
||||||
}
|
}
|
||||||
|
if (us_drm_ensure_no_signal(stream->drm) < 0) {
|
||||||
ldf now_ts = us_get_now_monotonic();
|
goto close;
|
||||||
if (run->drm_blank_at_ts == 0) {
|
|
||||||
run->drm_blank_at_ts = now_ts + 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now_ts <= run->drm_blank_at_ts) {
|
|
||||||
CHECK(us_drm_wait_for_vsync(run->drm));
|
|
||||||
CHECK(us_drm_expose_stub(run->drm, US_DRM_STUB_NO_SIGNAL, NULL));
|
|
||||||
} else {
|
|
||||||
// US_ONCE({ US_LOG_INFO("DRM: Turning off the display by timeout ..."); });
|
|
||||||
CHECK(us_drm_dpms_power_off(run->drm));
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
# undef CHECK
|
|
||||||
|
|
||||||
close:
|
close:
|
||||||
us_drm_close(run->drm);
|
us_drm_close(stream->drm);
|
||||||
run->drm_opened = -1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,6 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
us_h264_stream_s *h264;
|
us_h264_stream_s *h264;
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
|
||||||
us_drm_s *drm;
|
|
||||||
int drm_opened;
|
|
||||||
ldf drm_blank_at_ts;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
us_ring_s *http_jpeg_ring;
|
us_ring_s *http_jpeg_ring;
|
||||||
atomic_bool http_has_clients;
|
atomic_bool http_has_clients;
|
||||||
atomic_uint http_snapshot_requested;
|
atomic_uint http_snapshot_requested;
|
||||||
@@ -78,7 +72,7 @@ typedef struct {
|
|||||||
char *h264_m2m_path;
|
char *h264_m2m_path;
|
||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
bool v4p;
|
us_drm_s *drm;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
us_stream_runtime_s *run;
|
us_stream_runtime_s *run;
|
||||||
|
|||||||
@@ -174,18 +174,14 @@ static void _main_loop(void) {
|
|||||||
cap->dma_required = true;
|
cap->dma_required = true;
|
||||||
|
|
||||||
int once = 0;
|
int once = 0;
|
||||||
ldf blank_at_ts = 0;
|
|
||||||
int drm_opened = -1;
|
|
||||||
while (!atomic_load(&_g_stop)) {
|
while (!atomic_load(&_g_stop)) {
|
||||||
# define CHECK(x_arg) if ((x_arg) < 0) { goto close; }
|
# define CHECK(x_arg) if ((x_arg) < 0) { goto close; }
|
||||||
|
|
||||||
if (drm_opened <= 0) {
|
if (drm->run->opened <= 0) {
|
||||||
blank_at_ts = 0;
|
CHECK(us_drm_open(drm, NULL));
|
||||||
CHECK(drm_opened = us_drm_open(drm, NULL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_load(&_g_ustreamer_online)) {
|
if (atomic_load(&_g_ustreamer_online)) {
|
||||||
blank_at_ts = 0;
|
|
||||||
US_ONCE({ US_LOG_INFO("DRM: Online stream is active, pausing the service ..."); });
|
US_ONCE({ US_LOG_INFO("DRM: Online stream is active, pausing the service ..."); });
|
||||||
CHECK(us_drm_wait_for_vsync(drm));
|
CHECK(us_drm_wait_for_vsync(drm));
|
||||||
CHECK(us_drm_expose_stub(drm, US_DRM_STUB_BUSY, NULL));
|
CHECK(us_drm_expose_stub(drm, US_DRM_STUB_BUSY, NULL));
|
||||||
@@ -194,25 +190,14 @@ static void _main_loop(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (us_capture_open(cap) < 0) {
|
if (us_capture_open(cap) < 0) {
|
||||||
ldf now_ts = us_get_now_monotonic();
|
CHECK(us_drm_ensure_no_signal(drm));
|
||||||
if (blank_at_ts == 0) {
|
|
||||||
blank_at_ts = now_ts + 5;
|
|
||||||
}
|
|
||||||
if (now_ts <= blank_at_ts) {
|
|
||||||
CHECK(us_drm_wait_for_vsync(drm));
|
|
||||||
CHECK(us_drm_expose_stub(drm, US_DRM_STUB_NO_SIGNAL, NULL));
|
|
||||||
} else {
|
|
||||||
US_ONCE({ US_LOG_INFO("DRM: Turning off the display by timeout ..."); });
|
|
||||||
CHECK(us_drm_dpms_power_off(drm));
|
|
||||||
}
|
|
||||||
_slowdown();
|
_slowdown();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
once = 0;
|
once = 0;
|
||||||
blank_at_ts = 0;
|
|
||||||
us_drm_close(drm);
|
us_drm_close(drm);
|
||||||
CHECK(drm_opened = us_drm_open(drm, cap));
|
CHECK(us_drm_open(drm, cap));
|
||||||
|
|
||||||
us_capture_hwbuf_s *prev_hw = NULL;
|
us_capture_hwbuf_s *prev_hw = NULL;
|
||||||
while (!atomic_load(&_g_stop)) {
|
while (!atomic_load(&_g_stop)) {
|
||||||
@@ -234,23 +219,20 @@ static void _main_loop(void) {
|
|||||||
default: goto close; // Any error
|
default: goto close; // Any error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drm_opened == 0) {
|
if (drm->run->opened == 0) {
|
||||||
CHECK(us_drm_expose_dma(drm, hw));
|
CHECK(us_drm_expose_dma(drm, hw));
|
||||||
prev_hw = hw;
|
prev_hw = hw;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(us_drm_expose_stub(drm, drm_opened, cap));
|
CHECK(us_drm_expose_stub(drm, drm->run->opened, cap));
|
||||||
CHECK(us_capture_hwbuf_release(cap, hw));
|
CHECK(us_capture_hwbuf_release(cap, hw));
|
||||||
_slowdown();
|
_slowdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
close:
|
close:
|
||||||
us_drm_close(drm);
|
us_drm_close(drm);
|
||||||
drm_opened = -1;
|
|
||||||
|
|
||||||
us_capture_close(cap);
|
us_capture_close(cap);
|
||||||
|
|
||||||
_slowdown();
|
_slowdown();
|
||||||
|
|
||||||
# undef CHECK
|
# undef CHECK
|
||||||
|
|||||||
Reference in New Issue
Block a user