refactoring

This commit is contained in:
Devaev Maxim
2021-01-09 15:08:34 +03:00
parent 310e30fdff
commit 1e6c3b9708
3 changed files with 61 additions and 47 deletions

View File

@@ -42,6 +42,7 @@ static bool _expose_new_frame(server_s *server);
#define RUN(_next) server->run->_next #define RUN(_next) server->run->_next
#define STREAM(_next) RUN(stream->_next) #define STREAM(_next) RUN(stream->_next)
#define VID(_next) STREAM(run->video->_next)
#define EX(_next) RUN(exposed->_next) #define EX(_next) RUN(exposed->_next)
@@ -747,7 +748,7 @@ static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_serv
bool stream_updated = false; bool stream_updated = false;
bool frame_updated = false; bool frame_updated = false;
if (atomic_load(&STREAM(video->updated))) { if (atomic_load(&VID(updated))) {
frame_updated = _expose_new_frame(server); frame_updated = _expose_new_frame(server);
stream_updated = true; stream_updated = true;
} else if (EX(expose_end_ts) + 1 < get_now_monotonic()) { } else if (EX(expose_end_ts) + 1 < get_now_monotonic()) {
@@ -780,19 +781,19 @@ static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_serv
static bool _expose_new_frame(server_s *server) { static bool _expose_new_frame(server_s *server) {
bool updated = false; bool updated = false;
A_MUTEX_LOCK(&STREAM(video->mutex)); A_MUTEX_LOCK(&VID(mutex));
LOG_DEBUG("HTTP: Updating exposed frame (online=%d) ...", STREAM(video->frame->online)); LOG_DEBUG("HTTP: Updating exposed frame (online=%d) ...", VID(frame->online));
EX(captured_fps) = STREAM(video->captured_fps); EX(captured_fps) = VID(captured_fps);
EX(expose_begin_ts) = get_now_monotonic(); EX(expose_begin_ts) = get_now_monotonic();
if (server->drop_same_frames && STREAM(video->frame->online)) { if (server->drop_same_frames && VID(frame->online)) {
bool need_drop = false; bool need_drop = false;
bool maybe_same = false; bool maybe_same = false;
if ( if (
(need_drop = (EX(dropped) < server->drop_same_frames)) (need_drop = (EX(dropped) < server->drop_same_frames))
&& (maybe_same = frame_compare(EX(frame), STREAM(video->frame))) && (maybe_same = frame_compare(EX(frame), VID(frame)))
) { ) {
EX(expose_cmp_ts) = get_now_monotonic(); EX(expose_cmp_ts) = get_now_monotonic();
EX(expose_end_ts) = EX(expose_cmp_ts); EX(expose_end_ts) = EX(expose_cmp_ts);
@@ -807,7 +808,7 @@ static bool _expose_new_frame(server_s *server) {
} }
} }
frame_copy(STREAM(video->frame), EX(frame)); frame_copy(VID(frame), EX(frame));
EX(dropped) = 0; EX(dropped) = 0;
EX(expose_cmp_ts) = EX(expose_begin_ts); EX(expose_cmp_ts) = EX(expose_begin_ts);
@@ -818,11 +819,12 @@ static bool _expose_new_frame(server_s *server) {
updated = true; updated = true;
not_updated: not_updated:
atomic_store(&STREAM(video->updated), false); atomic_store(&VID(updated), false);
A_MUTEX_UNLOCK(&STREAM(video->mutex)); A_MUTEX_UNLOCK(&VID(mutex));
return updated; return updated;
} }
#undef EX #undef EX
#undef VID
#undef STREAM #undef STREAM
#undef RUN #undef RUN

View File

@@ -34,42 +34,47 @@ static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame);
#endif #endif
#define RUN(_next) stream->run->_next
stream_s *stream_init(device_s *dev, encoder_s *enc) { stream_s *stream_init(device_s *dev, encoder_s *enc) {
process_s *proc; stream_runtime_s *run;
A_CALLOC(proc, 1); A_CALLOC(run, 1);
atomic_init(&proc->stop, false); atomic_init(&run->stop, false);
atomic_init(&proc->slowdown, false); atomic_init(&run->slowdown, false);
video_s *video; video_s *video;
A_CALLOC(video, 1); A_CALLOC(video, 1);
video->frame = frame_init("stream_video"); video->frame = frame_init("stream_video");
atomic_init(&video->updated, false); atomic_init(&video->updated, false);
A_MUTEX_INIT(&video->mutex); A_MUTEX_INIT(&video->mutex);
run->video = video;
stream_s *stream; stream_s *stream;
A_CALLOC(stream, 1); A_CALLOC(stream, 1);
stream->dev = dev;
stream->enc = enc;
stream->last_as_blank = -1; stream->last_as_blank = -1;
stream->error_delay = 1; stream->error_delay = 1;
# ifdef WITH_OMX # ifdef WITH_OMX
stream->h264_bitrate = 5000; // Kbps stream->h264_bitrate = 5000; // Kbps
stream->h264_gop = 30; stream->h264_gop = 30;
# endif # endif
stream->proc = proc; stream->run = run;
stream->video = video;
stream->dev = dev;
stream->enc = enc;
return stream; return stream;
} }
void stream_destroy(stream_s *stream) { void stream_destroy(stream_s *stream) {
A_MUTEX_DESTROY(&stream->video->mutex); A_MUTEX_DESTROY(&RUN(video->mutex));
frame_destroy(stream->video->frame); frame_destroy(RUN(video->frame));
free(stream->video); free(RUN(video));
free(stream->proc); free(stream->run);
free(stream); free(stream);
} }
void stream_loop(stream_s *stream) { void stream_loop(stream_s *stream) {
assert(stream->blank);
LOG_INFO("Using V4L2 device: %s", stream->dev->path); LOG_INFO("Using V4L2 device: %s", stream->dev->path);
LOG_INFO("Using desired FPS: %u", stream->dev->desired_fps); LOG_INFO("Using desired FPS: %u", stream->dev->desired_fps);
@@ -88,7 +93,7 @@ void stream_loop(stream_s *stream) {
LOG_INFO("Capturing ..."); LOG_INFO("Capturing ...");
while (!atomic_load(&stream->proc->stop)) { while (!atomic_load(&RUN(stop))) {
SEP_DEBUG('-'); SEP_DEBUG('-');
LOG_DEBUG("Waiting for worker ..."); LOG_DEBUG("Waiting for worker ...");
@@ -116,11 +121,11 @@ void stream_loop(stream_s *stream) {
} }
} }
if (atomic_load(&stream->proc->stop)) { if (atomic_load(&RUN(stop))) {
break; break;
} }
if (atomic_load(&stream->proc->slowdown)) { if (atomic_load(&RUN(slowdown))) {
usleep(1000000); usleep(1000000);
} }
@@ -221,11 +226,11 @@ void stream_loop(stream_s *stream) {
} }
void stream_loop_break(stream_s *stream) { void stream_loop_break(stream_s *stream) {
atomic_store(&stream->proc->stop, true); atomic_store(&RUN(stop), true);
} }
void stream_switch_slowdown(stream_s *stream, bool slowdown) { void stream_switch_slowdown(stream_s *stream, bool slowdown) {
atomic_store(&stream->proc->slowdown, slowdown); atomic_store(&RUN(slowdown), slowdown);
} }
static workers_pool_s *_stream_init_loop(stream_s *stream) { static workers_pool_s *_stream_init_loop(stream_s *stream) {
@@ -233,9 +238,9 @@ static workers_pool_s *_stream_init_loop(stream_s *stream) {
workers_pool_s *pool = NULL; workers_pool_s *pool = NULL;
int access_error = 0; int access_error = 0;
LOG_DEBUG("%s: stream->proc->stop=%d", __FUNCTION__, atomic_load(&stream->proc->stop)); LOG_DEBUG("%s: stream->run->stop=%d", __FUNCTION__, atomic_load(&RUN(stop)));
while (!atomic_load(&stream->proc->stop)) { while (!atomic_load(&RUN(stop))) {
if (_stream_expose_frame(stream, NULL, 0)) { if (_stream_expose_frame(stream, NULL, 0)) {
if (stream->jpeg_sink) { if (stream->jpeg_sink) {
memsink_server_put(stream->jpeg_sink, stream->blank); memsink_server_put(stream->jpeg_sink, stream->blank);
@@ -285,7 +290,7 @@ static workers_pool_s *_stream_init_one(stream_s *stream) {
} }
static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps) { static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps) {
# define VID(_next) stream->video->_next # define VID(_next) RUN(video->_next)
frame_s *new = NULL; frame_s *new = NULL;
bool changed = false; bool changed = false;
@@ -294,7 +299,7 @@ static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned capt
if (frame) { if (frame) {
new = frame; new = frame;
VID(last_as_blank_ts) = 0; // Останавливаем таймер RUN(last_as_blank_ts) = 0; // Останавливаем таймер
LOG_DEBUG("Exposed ALIVE video frame"); LOG_DEBUG("Exposed ALIVE video frame");
} else { } else {
@@ -303,7 +308,7 @@ static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned capt
new = stream->blank; new = stream->blank;
LOG_INFO("Changed video frame to BLANK"); LOG_INFO("Changed video frame to BLANK");
} else if (stream->last_as_blank > 0) { // // Если нужен таймер - запустим } else if (stream->last_as_blank > 0) { // // Если нужен таймер - запустим
VID(last_as_blank_ts) = get_now_monotonic() + stream->last_as_blank; RUN(last_as_blank_ts) = get_now_monotonic() + stream->last_as_blank;
LOG_INFO("Freezed last ALIVE video frame for %d seconds", stream->last_as_blank); LOG_INFO("Freezed last ALIVE video frame for %d seconds", stream->last_as_blank);
} else { // last_as_blank == 0 - показываем последний фрейм вечно } else { // last_as_blank == 0 - показываем последний фрейм вечно
LOG_INFO("Freezed last ALIVE video frame forever"); LOG_INFO("Freezed last ALIVE video frame forever");
@@ -315,11 +320,11 @@ static bool _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned capt
if ( // Если уже оффлайн, включена фича last_as_blank с таймером и он запущен if ( // Если уже оффлайн, включена фича last_as_blank с таймером и он запущен
stream->last_as_blank > 0 stream->last_as_blank > 0
&& VID(last_as_blank_ts) != 0 && RUN(last_as_blank_ts) != 0
&& VID(last_as_blank_ts) < get_now_monotonic() && RUN(last_as_blank_ts) < get_now_monotonic()
) { ) {
new = stream->blank; new = stream->blank;
VID(last_as_blank_ts) = 0; // // Останавливаем таймер RUN(last_as_blank_ts) = 0; // // Останавливаем таймер
LOG_INFO("Changed last ALIVE video frame to BLANK"); LOG_INFO("Changed last ALIVE video frame to BLANK");
} }
} }
@@ -395,3 +400,5 @@ static void _h264_stream_process(h264_stream_s *h264, const frame_s *frame) {
} }
} }
#endif #endif
#undef RUN

View File

@@ -51,16 +51,10 @@
#endif #endif
typedef struct {
atomic_bool stop;
atomic_bool slowdown;
} process_s;
typedef struct { typedef struct {
frame_s *frame; frame_s *frame;
unsigned captured_fps; unsigned captured_fps;
atomic_bool updated; atomic_bool updated;
long double last_as_blank_ts;
pthread_mutex_t mutex; pthread_mutex_t mutex;
} video_s; } video_s;
@@ -74,24 +68,35 @@ typedef struct {
#endif #endif
typedef struct { typedef struct {
video_s *video;
long double last_as_blank_ts;
# ifdef WITH_OMX
h264_stream_s *h264;
# endif
atomic_bool stop;
atomic_bool slowdown;
} stream_runtime_s;
typedef struct {
device_s *dev;
encoder_s *enc;
int last_as_blank; int last_as_blank;
unsigned error_delay; unsigned error_delay;
device_s *dev;
encoder_s *enc;
frame_s *blank; frame_s *blank;
memsink_s *jpeg_sink; memsink_s *jpeg_sink;
# ifdef WITH_OMX # ifdef WITH_OMX
memsink_s *h264_sink; memsink_s *h264_sink;
unsigned h264_bitrate; unsigned h264_bitrate;
unsigned h264_gop; unsigned h264_gop;
# endif # endif
process_s *proc; stream_runtime_s *run;
video_s *video;
# ifdef WITH_OMX
h264_stream_s *h264;
# endif
} stream_s; } stream_s;