mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-14 11:33:43 +00:00
refactoring
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user