fixed force_key logic for slowdown

This commit is contained in:
Maxim Devaev 2024-03-03 02:51:53 +02:00
parent 8f6df3b455
commit 988a91634a
4 changed files with 34 additions and 14 deletions

View File

@ -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)",

View File

@ -22,8 +22,19 @@
#include "h264.h"
#include <stdatomic.h>
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) {

View File

@ -22,15 +22,12 @@
#pragma once
#include <stdbool.h>
#include <stdatomic.h>
#include <assert.h>
#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);

View File

@ -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('=');