mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-11 18:13:41 +00:00
using fps_meta instead of flags
This commit is contained in:
@@ -251,7 +251,7 @@ static int _dump_sink(
|
|||||||
US_LOG_DEBUG(" stride=%u, grab_ts=%.3Lf, encode_begin_ts=%.3Lf, encode_end_ts=%.3Lf",
|
US_LOG_DEBUG(" stride=%u, grab_ts=%.3Lf, encode_begin_ts=%.3Lf, encode_end_ts=%.3Lf",
|
||||||
frame->stride, frame->grab_ts, frame->encode_begin_ts, frame->encode_end_ts);
|
frame->stride, frame->grab_ts, frame->encode_begin_ts, frame->encode_end_ts);
|
||||||
|
|
||||||
us_fpsi_bump(fpsi, NULL, false);
|
us_fpsi_update(fpsi, true, NULL);
|
||||||
|
|
||||||
if (ctx->v_output != NULL) {
|
if (ctx->v_output != NULL) {
|
||||||
ctx->write(ctx->v_output, frame);
|
ctx->write(ctx->v_output, frame);
|
||||||
|
|||||||
@@ -48,8 +48,14 @@ void us_fpsi_destroy(us_fpsi_s *fpsi) {
|
|||||||
free(fpsi);
|
free(fpsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void us_fpsi_bump(us_fpsi_s *fpsi, const us_frame_s *frame, bool noop_accum) {
|
void us_fpsi_frame_to_meta(const us_frame_s *frame, us_fpsi_meta_s *meta) {
|
||||||
if (frame != NULL) {
|
meta->width = frame->width;
|
||||||
|
meta->height = frame->height;
|
||||||
|
meta->online = frame->online;
|
||||||
|
}
|
||||||
|
|
||||||
|
void us_fpsi_update(us_fpsi_s *fpsi, bool bump, const us_fpsi_meta_s *meta) {
|
||||||
|
if (meta != NULL) {
|
||||||
assert(fpsi->with_meta);
|
assert(fpsi->with_meta);
|
||||||
} else {
|
} else {
|
||||||
assert(!fpsi->with_meta);
|
assert(!fpsi->with_meta);
|
||||||
@@ -62,16 +68,16 @@ void us_fpsi_bump(us_fpsi_s *fpsi, const us_frame_s *frame, bool noop_accum) {
|
|||||||
// Fast mutex-less store method
|
// Fast mutex-less store method
|
||||||
ull state = (ull)fpsi->accum & 0xFFFF;
|
ull state = (ull)fpsi->accum & 0xFFFF;
|
||||||
if (fpsi->with_meta) {
|
if (fpsi->with_meta) {
|
||||||
assert(frame != NULL);
|
assert(meta != NULL);
|
||||||
state |= (ull)(frame->width & 0xFFFF) << 16;
|
state |= (ull)(meta->width & 0xFFFF) << 16;
|
||||||
state |= (ull)(frame->height & 0xFFFF) << 32;
|
state |= (ull)(meta->height & 0xFFFF) << 32;
|
||||||
state |= (ull)(frame->online ? 1 : 0) << 48;
|
state |= (ull)(meta->online ? 1 : 0) << 48;
|
||||||
}
|
}
|
||||||
atomic_store(&fpsi->state, state); // Сначала инфа
|
atomic_store(&fpsi->state, state); // Сначала инфа
|
||||||
atomic_store(&fpsi->state_sec_ts, now_sec_ts); // Потом время, это важно
|
atomic_store(&fpsi->state_sec_ts, now_sec_ts); // Потом время, это важно
|
||||||
fpsi->accum = 0;
|
fpsi->accum = 0;
|
||||||
}
|
}
|
||||||
if (!noop_accum) {
|
if (bump) {
|
||||||
++fpsi->accum;
|
++fpsi->accum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,5 +46,6 @@ typedef struct {
|
|||||||
us_fpsi_s *us_fpsi_init(const char *name, bool with_meta);
|
us_fpsi_s *us_fpsi_init(const char *name, bool with_meta);
|
||||||
void us_fpsi_destroy(us_fpsi_s *fpsi);
|
void us_fpsi_destroy(us_fpsi_s *fpsi);
|
||||||
|
|
||||||
void us_fpsi_bump(us_fpsi_s *fpsi, const us_frame_s *frame, bool noop_accum);
|
void us_fpsi_frame_to_meta(const us_frame_s *frame, us_fpsi_meta_s *meta);
|
||||||
|
void us_fpsi_update(us_fpsi_s *fpsi, bool bump, const us_fpsi_meta_s *meta);
|
||||||
uint us_fpsi_get(us_fpsi_s *fpsi, us_fpsi_meta_s *meta);
|
uint us_fpsi_get(us_fpsi_s *fpsi, us_fpsi_meta_s *meta);
|
||||||
|
|||||||
@@ -478,21 +478,25 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
|||||||
|
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
if (stream->drm != NULL) {
|
if (stream->drm != NULL) {
|
||||||
|
us_fpsi_meta_s meta;
|
||||||
|
const uint fps = us_fpsi_get(stream->run->http->drm_fpsi, &meta);
|
||||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||||
" \"drm\": {\"live\": %s, \"fps\": %u},",
|
" \"drm\": {\"live\": %s, \"fps\": %u},",
|
||||||
us_bool_to_string(atomic_load(&stream->run->http->drm_live)),
|
us_bool_to_string(meta.online),
|
||||||
us_fpsi_get(stream->run->http->drm_fpsi, NULL)
|
fps
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (stream->h264_sink != NULL) {
|
if (stream->h264_sink != NULL) {
|
||||||
|
us_fpsi_meta_s meta;
|
||||||
|
const uint fps = us_fpsi_get(stream->run->http->h264_fpsi, &meta);
|
||||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||||
" \"h264\": {\"bitrate\": %u, \"gop\": %u, \"online\": %s, \"fps\": %u},",
|
" \"h264\": {\"bitrate\": %u, \"gop\": %u, \"online\": %s, \"fps\": %u},",
|
||||||
stream->h264_bitrate,
|
stream->h264_bitrate,
|
||||||
stream->h264_gop,
|
stream->h264_gop,
|
||||||
us_bool_to_string(atomic_load(&stream->run->http->h264_online)),
|
us_bool_to_string(meta.online),
|
||||||
us_fpsi_get(stream->run->http->h264_fpsi, NULL)
|
fps
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,7 +648,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
|||||||
us_server_s *const server = client->server;
|
us_server_s *const server = client->server;
|
||||||
us_server_exposed_s *const ex = server->run->exposed;
|
us_server_exposed_s *const ex = server->run->exposed;
|
||||||
|
|
||||||
us_fpsi_bump(client->fpsi, NULL, false);
|
us_fpsi_update(client->fpsi, true, NULL);
|
||||||
|
|
||||||
struct evbuffer *buf;
|
struct evbuffer *buf;
|
||||||
_A_EVBUFFER_NEW(buf);
|
_A_EVBUFFER_NEW(buf);
|
||||||
@@ -850,9 +854,9 @@ static void _http_send_stream(us_server_s *server, bool stream_updated, bool fra
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (queued) {
|
if (queued) {
|
||||||
us_fpsi_bump(ex->queued_fpsi, NULL, false);
|
us_fpsi_update(ex->queued_fpsi, true, NULL);
|
||||||
} else if (!has_clients) {
|
} else if (!has_clients) {
|
||||||
us_fpsi_bump(ex->queued_fpsi, NULL, true);
|
us_fpsi_update(ex->queued_fpsi, false, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,11 +98,9 @@ us_stream_s *us_stream_init(us_capture_s *cap, us_encoder_s *enc) {
|
|||||||
us_stream_http_s *http;
|
us_stream_http_s *http;
|
||||||
US_CALLOC(http, 1);
|
US_CALLOC(http, 1);
|
||||||
# ifdef WITH_V4P
|
# ifdef WITH_V4P
|
||||||
atomic_init(&http->drm_live, false);
|
http->drm_fpsi = us_fpsi_init("DRM", true);
|
||||||
http->drm_fpsi = us_fpsi_init("DRM", false);
|
|
||||||
# endif
|
# endif
|
||||||
atomic_init(&http->h264_online, false);
|
http->h264_fpsi = us_fpsi_init("H264", true);
|
||||||
http->h264_fpsi = us_fpsi_init("H264", false);
|
|
||||||
US_RING_INIT_WITH_ITEMS(http->jpeg_ring, 4, us_frame_init);
|
US_RING_INIT_WITH_ITEMS(http->jpeg_ring, 4, us_frame_init);
|
||||||
atomic_init(&http->has_clients, false);
|
atomic_init(&http->has_clients, false);
|
||||||
atomic_init(&http->snapshot_requested, 0);
|
atomic_init(&http->snapshot_requested, 0);
|
||||||
@@ -125,7 +123,9 @@ us_stream_s *us_stream_init(us_capture_s *cap, us_encoder_s *enc) {
|
|||||||
stream->run = run;
|
stream->run = run;
|
||||||
|
|
||||||
us_blank_draw(run->blank, "< NO SIGNAL >", cap->width, cap->height);
|
us_blank_draw(run->blank, "< NO SIGNAL >", cap->width, cap->height);
|
||||||
us_fpsi_bump(http->captured_fpsi, run->blank->raw, true);
|
us_fpsi_meta_s meta = {0};
|
||||||
|
us_fpsi_frame_to_meta(run->blank->raw, &meta);
|
||||||
|
us_fpsi_update(http->captured_fpsi, false, &meta);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,9 @@ void us_stream_loop(us_stream_s *stream) {
|
|||||||
default: goto close; // Any error
|
default: goto close; // Any error
|
||||||
}
|
}
|
||||||
|
|
||||||
us_fpsi_bump(run->http->captured_fpsi, &hw->raw, false);
|
us_fpsi_meta_s meta = {0};
|
||||||
|
us_fpsi_frame_to_meta(&hw->raw, &meta);
|
||||||
|
us_fpsi_update(run->http->captured_fpsi, true, &meta);
|
||||||
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
us_gpio_set_stream_online(true);
|
us_gpio_set_stream_online(true);
|
||||||
@@ -459,15 +461,16 @@ static void *_drm_thread(void *v_ctx) {
|
|||||||
if (stream->drm->run->opened == 0) {
|
if (stream->drm->run->opened == 0) {
|
||||||
CHECK(us_drm_expose_dma(stream->drm, hw));
|
CHECK(us_drm_expose_dma(stream->drm, hw));
|
||||||
prev_hw = hw;
|
prev_hw = hw;
|
||||||
atomic_store(&stream->run->http->drm_live, true);
|
us_fpsi_meta_s meta = {.online = true}; // Online means live video
|
||||||
us_fpsi_bump(stream->run->http->drm_fpsi, NULL, false);
|
us_fpsi_update(stream->run->http->drm_fpsi, true, &meta);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(us_drm_expose_stub(stream->drm, stream->drm->run->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);
|
||||||
|
|
||||||
us_fpsi_bump(stream->run->http->drm_fpsi, NULL, false);
|
us_fpsi_meta_s meta = {.online = false};
|
||||||
|
us_fpsi_update(stream->run->http->drm_fpsi, true, &meta);
|
||||||
|
|
||||||
SLOWDOWN;
|
SLOWDOWN;
|
||||||
}
|
}
|
||||||
@@ -475,9 +478,8 @@ static void *_drm_thread(void *v_ctx) {
|
|||||||
close:
|
close:
|
||||||
us_drm_close(stream->drm);
|
us_drm_close(stream->drm);
|
||||||
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
US_DELETE(prev_hw, us_capture_hwbuf_decref);
|
||||||
|
us_fpsi_meta_s meta = {.online = false};
|
||||||
atomic_store(&stream->run->http->drm_live, false);
|
us_fpsi_update(stream->run->http->drm_fpsi, false, &meta);
|
||||||
|
|
||||||
SLOWDOWN;
|
SLOWDOWN;
|
||||||
|
|
||||||
# undef SLOWDOWN
|
# undef SLOWDOWN
|
||||||
@@ -573,7 +575,10 @@ static int _stream_init_loop(us_stream_s *stream) {
|
|||||||
height = stream->cap->height;
|
height = stream->cap->height;
|
||||||
}
|
}
|
||||||
us_blank_draw(run->blank, "< NO SIGNAL >", width, height);
|
us_blank_draw(run->blank, "< NO SIGNAL >", width, height);
|
||||||
us_fpsi_bump(run->http->captured_fpsi, run->blank->raw, true);
|
|
||||||
|
us_fpsi_meta_s meta = {0};
|
||||||
|
us_fpsi_frame_to_meta(run->blank->raw, &meta);
|
||||||
|
us_fpsi_update(run->http->captured_fpsi, false, &meta);
|
||||||
|
|
||||||
_stream_expose_jpeg(stream, run->blank->jpeg);
|
_stream_expose_jpeg(stream, run->blank->jpeg);
|
||||||
_stream_expose_raw(stream, run->blank->raw);
|
_stream_expose_raw(stream, run->blank->raw);
|
||||||
@@ -594,7 +599,8 @@ static void _stream_drm_ensure_no_signal(us_stream_s *stream) {
|
|||||||
if (stream->drm == NULL) {
|
if (stream->drm == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
atomic_store(&stream->run->http->drm_live, false);
|
|
||||||
|
const us_fpsi_meta_s meta = {.online = false};
|
||||||
if (stream->drm->run->opened <= 0) {
|
if (stream->drm->run->opened <= 0) {
|
||||||
us_drm_close(stream->drm);
|
us_drm_close(stream->drm);
|
||||||
if (us_drm_open(stream->drm, NULL) < 0) {
|
if (us_drm_open(stream->drm, NULL) < 0) {
|
||||||
@@ -604,9 +610,12 @@ static void _stream_drm_ensure_no_signal(us_stream_s *stream) {
|
|||||||
if (us_drm_ensure_no_signal(stream->drm) < 0) {
|
if (us_drm_ensure_no_signal(stream->drm) < 0) {
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
us_fpsi_bump(stream->run->http->drm_fpsi, NULL, false);
|
|
||||||
|
us_fpsi_update(stream->run->http->drm_fpsi, true, &meta);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
close:
|
close:
|
||||||
|
us_fpsi_update(stream->run->http->drm_fpsi, false, &meta);
|
||||||
us_drm_close(stream->drm);
|
us_drm_close(stream->drm);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -639,26 +648,25 @@ static void _stream_encode_expose_h264(us_stream_s *stream, const us_frame_s *fr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool online = false;
|
us_fpsi_meta_s meta = {.online = false};
|
||||||
|
|
||||||
if (us_is_jpeg(frame->format)) {
|
if (us_is_jpeg(frame->format)) {
|
||||||
if (us_unjpeg(frame, run->h264_tmp_src, true) < 0) {
|
if (us_unjpeg(frame, run->h264_tmp_src, true) < 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
frame = run->h264_tmp_src;
|
frame = run->h264_tmp_src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run->h264_key_requested) {
|
if (run->h264_key_requested) {
|
||||||
US_LOG_INFO("H264: Requested keyframe by a sink client");
|
US_LOG_INFO("H264: Requested keyframe by a sink client");
|
||||||
run->h264_key_requested = false;
|
run->h264_key_requested = false;
|
||||||
force_key = true;
|
force_key = true;
|
||||||
}
|
}
|
||||||
if (!us_m2m_encoder_compress(run->h264_enc, frame, run->h264_dest, force_key)) {
|
if (!us_m2m_encoder_compress(run->h264_enc, frame, run->h264_dest, force_key)) {
|
||||||
online = !us_memsink_server_put(stream->h264_sink, run->h264_dest, &run->h264_key_requested);
|
meta.online = !us_memsink_server_put(stream->h264_sink, run->h264_dest, &run->h264_key_requested);
|
||||||
}
|
}
|
||||||
us_fpsi_bump(run->http->h264_fpsi, NULL, false);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
atomic_store(&run->http->h264_online, online);
|
us_fpsi_update(run->http->h264_fpsi, meta.online, &meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _stream_check_suicide(us_stream_s *stream) {
|
static void _stream_check_suicide(us_stream_s *stream) {
|
||||||
|
|||||||
Reference in New Issue
Block a user