From 988a91634af885aa553ff7e775870e4936ce0429 Mon Sep 17 00:00:00 2001 From: Maxim Devaev Date: Sun, 3 Mar 2024 02:51:53 +0200 Subject: [PATCH] fixed force_key logic for slowdown --- src/libs/memsink.c | 2 +- src/ustreamer/h264.c | 17 ++++++++++++++--- src/ustreamer/h264.h | 9 +++------ src/ustreamer/stream.c | 20 ++++++++++++++++---- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/libs/memsink.c b/src/libs/memsink.c index a7454c0..9929ee8 100644 --- a/src/libs/memsink.c +++ b/src/libs/memsink.c @@ -135,7 +135,7 @@ bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame) { int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key_requested) { assert(sink->server); - const long double now = us_get_now_monotonic(); + const ldf now = us_get_now_monotonic(); if (frame->used > US_MEMSINK_MAX_DATA) { US_LOG_ERROR("%s-sink: Can't put frame: is too big (%zu > %zu)", diff --git a/src/ustreamer/h264.c b/src/ustreamer/h264.c index bd857e1..245c456 100644 --- a/src/ustreamer/h264.c +++ b/src/ustreamer/h264.c @@ -22,8 +22,19 @@ #include "h264.h" +#include -us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, unsigned bitrate, unsigned gop) { +#include "../libs/types.h" +#include "../libs/tools.h" +#include "../libs/logging.h" +#include "../libs/frame.h" +#include "../libs/memsink.h" +#include "../libs/unjpeg.h" + +#include "m2m.h" + + +us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, uint bitrate, uint gop) { us_h264_stream_s *h264; US_CALLOC(h264, 1); h264->sink = sink; @@ -47,13 +58,13 @@ void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, boo } if (us_is_jpeg(frame->format)) { - const long double now = us_get_now_monotonic(); + const ldf now_ts = us_get_now_monotonic(); US_LOG_DEBUG("H264: Input frame is JPEG; decoding ..."); if (us_unjpeg(frame, h264->tmp_src, true) < 0) { return; } frame = h264->tmp_src; - US_LOG_VERBOSE("H264: JPEG decoded; time=%.3Lf", us_get_now_monotonic() - now); + US_LOG_VERBOSE("H264: JPEG decoded; time=%.3Lf", us_get_now_monotonic() - now_ts); } if (h264->key_requested) { diff --git a/src/ustreamer/h264.h b/src/ustreamer/h264.h index 8ad550e..6a4893c 100644 --- a/src/ustreamer/h264.h +++ b/src/ustreamer/h264.h @@ -22,15 +22,12 @@ #pragma once -#include #include -#include -#include "../libs/tools.h" -#include "../libs/logging.h" +#include "../libs/types.h" #include "../libs/frame.h" #include "../libs/memsink.h" -#include "../libs/unjpeg.h" + #include "m2m.h" @@ -44,6 +41,6 @@ typedef struct { } us_h264_stream_s; -us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, unsigned bitrate, unsigned gop); +us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, uint bitrate, uint gop); void us_h264_stream_destroy(us_h264_stream_s *h264); void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, bool force_key); diff --git a/src/ustreamer/stream.c b/src/ustreamer/stream.c index 2b86dbd..d804c60 100644 --- a/src/ustreamer/stream.c +++ b/src/ustreamer/stream.c @@ -301,12 +301,20 @@ static void *_jpeg_thread(void *v_ctx) { static void *_h264_thread(void *v_ctx) { _h264_context_s *ctx = v_ctx; + + ldf last_encode_ts = us_get_now_monotonic(); while (!atomic_load(ctx->stop)) { us_hw_buffer_s *hw; if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) { continue; } - us_h264_stream_process(ctx->h264, &hw->raw, false); + + // Форсим кейфрейм, если от захвата давно не было фреймов (при слоудауне) + const ldf now_ts = us_get_now_monotonic(); + const bool force_key = (last_encode_ts + 0.5 < now_ts); + last_encode_ts = now_ts; + + us_h264_stream_process(ctx->h264, &hw->raw, force_key); us_device_buffer_decref(hw); } return NULL; @@ -314,17 +322,20 @@ static void *_h264_thread(void *v_ctx) { static void *_releaser_thread(void *v_ctx) { _releaser_context_s *ctx = v_ctx; + while (!atomic_load(ctx->stop)) { us_hw_buffer_s *hw; if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) { continue; } + while (atomic_load(&hw->refs) > 0) { if (atomic_load(ctx->stop)) { goto done; } usleep(5 * 1000); } + US_MUTEX_LOCK(*ctx->mutex); const int released = us_device_release_buffer(ctx->dev, hw); US_MUTEX_UNLOCK(*ctx->mutex); @@ -332,6 +343,7 @@ static void *_releaser_thread(void *v_ctx) { goto done; } } + done: atomic_store(ctx->stop, true); // Stop all other guys on error return NULL; @@ -365,12 +377,12 @@ static int _stream_init_loop(us_stream_s *stream) { atomic_store(&run->http_captured_fps, 0); _stream_expose_frame(stream, NULL); - _SINK_PUT(raw_sink, run->blank->raw); - if (run->h264 != NULL) { - us_h264_stream_process(run->h264, run->blank->raw, false); + us_h264_stream_process(run->h264, run->blank->raw, true); } + _SINK_PUT(raw_sink, run->blank->raw); + if (access(stream->dev->path, R_OK|W_OK) < 0) { if (access_errno != errno) { US_SEP_INFO('=');