From d807f9fa8777a4fc4ef8c063a1fecd3d8e73d6fc Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Mon, 11 Jan 2021 14:36:41 +0300 Subject: [PATCH] force h264 keyframe on slowdown --- src/ustreamer/h264/encoder.c | 4 ++-- src/ustreamer/h264/encoder.h | 2 +- src/ustreamer/stream.c | 20 +++++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/ustreamer/h264/encoder.c b/src/ustreamer/h264/encoder.c index 90ca7cc..b5a9152 100644 --- a/src/ustreamer/h264/encoder.c +++ b/src/ustreamer/h264/encoder.c @@ -256,7 +256,7 @@ static void _h264_encoder_cleanup(h264_encoder_s *enc) { enc->ready = false; } -int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_handle, frame_s *dest) { +int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_handle, frame_s *dest, bool force_key) { assert(enc->ready); assert(src->used > 0); assert(enc->width == src->width); @@ -269,7 +269,7 @@ int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_ dest->format = V4L2_PIX_FMT_H264; dest->stride = 0; - bool force_key = (enc->last_online != src->online); + force_key = (force_key || enc->last_online != src->online); if (_h264_encoder_compress_raw(enc, src, src_vcsm_handle, dest, force_key) < 0) { _h264_encoder_cleanup(enc); diff --git a/src/ustreamer/h264/encoder.h b/src/ustreamer/h264/encoder.h index ef92f93..be5de71 100644 --- a/src/ustreamer/h264/encoder.h +++ b/src/ustreamer/h264/encoder.h @@ -67,4 +67,4 @@ void h264_encoder_destroy(h264_encoder_s *enc); bool h264_encoder_is_prepared_for(h264_encoder_s *enc, const frame_s *frame, bool zero_copy); int h264_encoder_prepare(h264_encoder_s *enc, const frame_s *frame, bool zero_copy); -int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_handle, frame_s *dest); +int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_handle, frame_s *dest, bool force_key); diff --git a/src/ustreamer/stream.c b/src/ustreamer/stream.c index 1fd9f26..f93bfdb 100644 --- a/src/ustreamer/stream.c +++ b/src/ustreamer/stream.c @@ -30,7 +30,7 @@ static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned capt #ifdef WITH_OMX static h264_stream_s *_h264_stream_init(memsink_s *sink, unsigned bitrate, unsigned gop); static void _h264_stream_destroy(h264_stream_s *h264); -static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame, int vcsm_handle); +static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame, int vcsm_handle, bool force_key); #endif @@ -118,8 +118,12 @@ void stream_loop(stream_s *stream) { } } +# ifdef WITH_OMX + bool h264_force_key = false; +# endif if (stream->slowdown) { - for (unsigned slc = 0; + unsigned slc = 0; + while ( slc < 10 && !atomic_load(&RUN(stop)) && !atomic_load(&RUN(video->has_clients)) @@ -128,9 +132,11 @@ void stream_loop(stream_s *stream) { # ifdef WITH_OMX && (RUN(h264) == NULL || /*RUN(h264->sink) == NULL ||*/ !RUN(h264->sink->has_clients)) # endif - ; ++slc) { + ) { usleep(100000); + ++slc; } + h264_force_key = (slc == 10); } if (atomic_load(&RUN(stop))) { @@ -194,7 +200,7 @@ void stream_loop(stream_s *stream) { # ifdef WITH_OMX if (RUN(h264)) { - _h264_stream_process(RUN(h264), &hw->raw, hw->vcsm_handle); + _h264_stream_process(RUN(h264), &hw->raw, hw->vcsm_handle, h264_force_key); } # endif } @@ -248,7 +254,7 @@ static workers_pool_s *_stream_init_loop(stream_s *stream) { if (_stream_expose_frame(stream, NULL, 0)) { # ifdef WITH_OMX if (RUN(h264)) { - _h264_stream_process(RUN(h264), stream->blank, -1); + _h264_stream_process(RUN(h264), stream->blank, -1, false); } # endif } @@ -386,7 +392,7 @@ static void _h264_stream_destroy(h264_stream_s *h264) { free(h264); } -static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame, int vcsm_handle) { +static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame, int vcsm_handle, bool force_key) { long double now = get_now_monotonic(); bool zero_copy = false; @@ -413,7 +419,7 @@ static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame, int } if (h264->enc->ready) { - if (h264_encoder_compress(h264->enc, frame, vcsm_handle, h264->dest) == 0) { + if (h264_encoder_compress(h264->enc, frame, vcsm_handle, h264->dest, force_key) == 0) { memsink_server_put(h264->sink, h264->dest); } }