mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-04-16 19:46:13 +00:00
fixed force_key logic for slowdown
This commit is contained in:
@@ -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) {
|
int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame, bool *key_requested) {
|
||||||
assert(sink->server);
|
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) {
|
if (frame->used > US_MEMSINK_MAX_DATA) {
|
||||||
US_LOG_ERROR("%s-sink: Can't put frame: is too big (%zu > %zu)",
|
US_LOG_ERROR("%s-sink: Can't put frame: is too big (%zu > %zu)",
|
||||||
|
|||||||
@@ -22,8 +22,19 @@
|
|||||||
|
|
||||||
#include "h264.h"
|
#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_h264_stream_s *h264;
|
||||||
US_CALLOC(h264, 1);
|
US_CALLOC(h264, 1);
|
||||||
h264->sink = sink;
|
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)) {
|
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 ...");
|
US_LOG_DEBUG("H264: Input frame is JPEG; decoding ...");
|
||||||
if (us_unjpeg(frame, h264->tmp_src, true) < 0) {
|
if (us_unjpeg(frame, h264->tmp_src, true) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
frame = h264->tmp_src;
|
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) {
|
if (h264->key_requested) {
|
||||||
|
|||||||
@@ -22,15 +22,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "../libs/tools.h"
|
#include "../libs/types.h"
|
||||||
#include "../libs/logging.h"
|
|
||||||
#include "../libs/frame.h"
|
#include "../libs/frame.h"
|
||||||
#include "../libs/memsink.h"
|
#include "../libs/memsink.h"
|
||||||
#include "../libs/unjpeg.h"
|
|
||||||
#include "m2m.h"
|
#include "m2m.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -44,6 +41,6 @@ typedef struct {
|
|||||||
} us_h264_stream_s;
|
} 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_destroy(us_h264_stream_s *h264);
|
||||||
void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, bool force_key);
|
void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, bool force_key);
|
||||||
|
|||||||
@@ -301,12 +301,20 @@ static void *_jpeg_thread(void *v_ctx) {
|
|||||||
|
|
||||||
static void *_h264_thread(void *v_ctx) {
|
static void *_h264_thread(void *v_ctx) {
|
||||||
_h264_context_s *ctx = v_ctx;
|
_h264_context_s *ctx = v_ctx;
|
||||||
|
|
||||||
|
ldf last_encode_ts = us_get_now_monotonic();
|
||||||
while (!atomic_load(ctx->stop)) {
|
while (!atomic_load(ctx->stop)) {
|
||||||
us_hw_buffer_s *hw;
|
us_hw_buffer_s *hw;
|
||||||
if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) {
|
if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) {
|
||||||
continue;
|
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);
|
us_device_buffer_decref(hw);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -314,17 +322,20 @@ static void *_h264_thread(void *v_ctx) {
|
|||||||
|
|
||||||
static void *_releaser_thread(void *v_ctx) {
|
static void *_releaser_thread(void *v_ctx) {
|
||||||
_releaser_context_s *ctx = v_ctx;
|
_releaser_context_s *ctx = v_ctx;
|
||||||
|
|
||||||
while (!atomic_load(ctx->stop)) {
|
while (!atomic_load(ctx->stop)) {
|
||||||
us_hw_buffer_s *hw;
|
us_hw_buffer_s *hw;
|
||||||
if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) {
|
if (us_queue_get(ctx->queue, (void**)&hw, 0.1) < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (atomic_load(&hw->refs) > 0) {
|
while (atomic_load(&hw->refs) > 0) {
|
||||||
if (atomic_load(ctx->stop)) {
|
if (atomic_load(ctx->stop)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
usleep(5 * 1000);
|
usleep(5 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
US_MUTEX_LOCK(*ctx->mutex);
|
US_MUTEX_LOCK(*ctx->mutex);
|
||||||
const int released = us_device_release_buffer(ctx->dev, hw);
|
const int released = us_device_release_buffer(ctx->dev, hw);
|
||||||
US_MUTEX_UNLOCK(*ctx->mutex);
|
US_MUTEX_UNLOCK(*ctx->mutex);
|
||||||
@@ -332,6 +343,7 @@ static void *_releaser_thread(void *v_ctx) {
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
atomic_store(ctx->stop, true); // Stop all other guys on error
|
atomic_store(ctx->stop, true); // Stop all other guys on error
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -365,12 +377,12 @@ static int _stream_init_loop(us_stream_s *stream) {
|
|||||||
atomic_store(&run->http_captured_fps, 0);
|
atomic_store(&run->http_captured_fps, 0);
|
||||||
_stream_expose_frame(stream, NULL);
|
_stream_expose_frame(stream, NULL);
|
||||||
|
|
||||||
_SINK_PUT(raw_sink, run->blank->raw);
|
|
||||||
|
|
||||||
if (run->h264 != NULL) {
|
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(stream->dev->path, R_OK|W_OK) < 0) {
|
||||||
if (access_errno != errno) {
|
if (access_errno != errno) {
|
||||||
US_SEP_INFO('=');
|
US_SEP_INFO('=');
|
||||||
|
|||||||
Reference in New Issue
Block a user