mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-04-11 00:56:13 +00:00
refactoring
This commit is contained in:
22
src/device.c
22
src/device.c
@@ -133,6 +133,28 @@ v4l2_std_id device_parse_standard(const char *str) {
|
||||
return STANDARD_UNKNOWN;
|
||||
}
|
||||
|
||||
void device_copy_picture(const struct picture_t *src, struct picture_t *dest) {
|
||||
# define COPY(_field) dest->_field = src->_field
|
||||
|
||||
if (dest->allocated < src->allocated) {
|
||||
A_REALLOC(dest->data, src->allocated);
|
||||
COPY(allocated);
|
||||
}
|
||||
|
||||
memcpy(dest->data, src->data, src->used);
|
||||
|
||||
COPY(used);
|
||||
|
||||
COPY(width);
|
||||
COPY(height);
|
||||
|
||||
COPY(grab_time);
|
||||
COPY(encode_begin_time);
|
||||
COPY(encode_end_time);
|
||||
|
||||
# undef COPY
|
||||
}
|
||||
|
||||
int device_open(struct device_t *dev) {
|
||||
if ((dev->run->fd = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) {
|
||||
LOG_PERROR("Can't open device");
|
||||
|
||||
@@ -54,6 +54,8 @@ struct picture_t {
|
||||
unsigned char *data;
|
||||
size_t used;
|
||||
size_t allocated;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
long double grab_time;
|
||||
long double encode_begin_time;
|
||||
long double encode_end_time;
|
||||
@@ -118,6 +120,8 @@ void device_destroy(struct device_t *dev);
|
||||
int device_parse_format(const char *str);
|
||||
v4l2_std_id device_parse_standard(const char *str);
|
||||
|
||||
void device_copy_picture(const struct picture_t *src, struct picture_t *dest);
|
||||
|
||||
int device_open(struct device_t *dev);
|
||||
void device_close(struct device_t *dev);
|
||||
|
||||
|
||||
@@ -217,6 +217,9 @@ int encoder_compress_buffer(struct encoder_t *encoder, struct device_t *dev, uns
|
||||
|
||||
dev->run->pictures[buf_index].encode_end_time = get_now_monotonic();
|
||||
|
||||
dev->run->pictures[buf_index].width = dev->run->width;
|
||||
dev->run->pictures[buf_index].height = dev->run->height;
|
||||
|
||||
return 0;
|
||||
|
||||
# pragma GCC diagnostic ignored "-Wunused-label"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "../tools.h"
|
||||
#include "../logging.h"
|
||||
#include "../device.h"
|
||||
|
||||
#include "data/blank_jpeg.h"
|
||||
|
||||
@@ -41,14 +42,14 @@ struct _jpeg_error_manager_t {
|
||||
};
|
||||
|
||||
|
||||
static struct blank_t *_blank_init_internal(void);
|
||||
static struct blank_t *_blank_init_external(const char *path);
|
||||
static struct picture_t *_blank_init_internal(void);
|
||||
static struct picture_t *_blank_init_external(const char *path);
|
||||
static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height);
|
||||
static void _jpeg_error_handler(j_common_ptr jpeg);
|
||||
|
||||
|
||||
struct blank_t *blank_init(const char *path) {
|
||||
struct blank_t *blank = NULL;
|
||||
struct picture_t *blank_init(const char *path) {
|
||||
struct picture_t *blank = NULL;
|
||||
|
||||
if (path) {
|
||||
blank = _blank_init_external(path);
|
||||
@@ -63,21 +64,21 @@ struct blank_t *blank_init(const char *path) {
|
||||
return blank;
|
||||
}
|
||||
|
||||
void blank_destroy(struct blank_t *blank) {
|
||||
free(blank->picture.data);
|
||||
void blank_destroy(struct picture_t *blank) {
|
||||
free(blank->data);
|
||||
free(blank);
|
||||
}
|
||||
|
||||
static struct blank_t *_blank_init_internal(void) {
|
||||
struct blank_t *blank;
|
||||
static struct picture_t *_blank_init_internal(void) {
|
||||
struct picture_t *blank;
|
||||
|
||||
A_CALLOC(blank, 1);
|
||||
|
||||
A_CALLOC(blank->picture.data, ARRAY_LEN(BLANK_JPEG_DATA));
|
||||
memcpy(blank->picture.data, BLANK_JPEG_DATA, ARRAY_LEN(BLANK_JPEG_DATA));
|
||||
A_CALLOC(blank->data, ARRAY_LEN(BLANK_JPEG_DATA));
|
||||
memcpy(blank->data, BLANK_JPEG_DATA, ARRAY_LEN(BLANK_JPEG_DATA));
|
||||
|
||||
blank->picture.used = ARRAY_LEN(BLANK_JPEG_DATA);
|
||||
blank->picture.allocated = ARRAY_LEN(BLANK_JPEG_DATA);
|
||||
blank->used = ARRAY_LEN(BLANK_JPEG_DATA);
|
||||
blank->allocated = ARRAY_LEN(BLANK_JPEG_DATA);
|
||||
|
||||
blank->width = BLANK_JPEG_WIDTH;
|
||||
blank->height = BLANK_JPEG_HEIGHT;
|
||||
@@ -85,9 +86,9 @@ static struct blank_t *_blank_init_internal(void) {
|
||||
return blank;
|
||||
}
|
||||
|
||||
static struct blank_t *_blank_init_external(const char *path) {
|
||||
static struct picture_t *_blank_init_external(const char *path) {
|
||||
FILE *fp = NULL;
|
||||
struct blank_t *blank;
|
||||
struct picture_t *blank;
|
||||
|
||||
A_CALLOC(blank, 1);
|
||||
|
||||
@@ -107,13 +108,13 @@ static struct blank_t *_blank_init_external(const char *path) {
|
||||
|
||||
# define CHUNK_SIZE (100 * 1024)
|
||||
while (true) {
|
||||
if (blank->picture.used + CHUNK_SIZE >= blank->picture.allocated) {
|
||||
blank->picture.allocated = blank->picture.used + CHUNK_SIZE * 2;
|
||||
A_REALLOC(blank->picture.data, blank->picture.allocated);
|
||||
if (blank->used + CHUNK_SIZE >= blank->allocated) {
|
||||
blank->allocated = blank->used + CHUNK_SIZE * 2;
|
||||
A_REALLOC(blank->data, blank->allocated);
|
||||
}
|
||||
|
||||
size_t readed = fread(blank->picture.data + blank->picture.used, 1, CHUNK_SIZE, fp);
|
||||
blank->picture.used += readed;
|
||||
size_t readed = fread(blank->data + blank->used, 1, CHUNK_SIZE, fp);
|
||||
blank->used += readed;
|
||||
|
||||
if (readed < CHUNK_SIZE) {
|
||||
if (feof(fp)) {
|
||||
@@ -127,7 +128,7 @@ static struct blank_t *_blank_init_external(const char *path) {
|
||||
# undef CHUNK_SIZE
|
||||
|
||||
error:
|
||||
free(blank->picture.data);
|
||||
free(blank->data);
|
||||
free(blank);
|
||||
blank = NULL;
|
||||
|
||||
|
||||
@@ -27,12 +27,5 @@
|
||||
#include "../device.h"
|
||||
|
||||
|
||||
struct blank_t {
|
||||
struct picture_t picture;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
|
||||
struct blank_t *blank_init(const char *path);
|
||||
void blank_destroy(struct blank_t *blank);
|
||||
struct picture_t *blank_init(const char *path);
|
||||
void blank_destroy(struct picture_t *blank);
|
||||
|
||||
@@ -436,8 +436,8 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
||||
" \"stream\": {\"queued_fps\": %u, \"clients\": %u, \"clients_stat\": {",
|
||||
encoder_type_to_string(encoder_run_type),
|
||||
encoder_run_quality,
|
||||
(server->fake_width ? server->fake_width : server->run->exposed->width),
|
||||
(server->fake_height ? server->fake_height : server->run->exposed->height),
|
||||
(server->fake_width ? server->fake_width : server->run->exposed->picture.width),
|
||||
(server->fake_height ? server->fake_height : server->run->exposed->picture.height),
|
||||
bool_to_string(server->run->exposed->online),
|
||||
server->run->stream->dev->desired_fps,
|
||||
server->run->exposed->captured_fps,
|
||||
@@ -497,8 +497,8 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv
|
||||
|
||||
ADD_HEADER("X-UStreamer-Online", bool_to_string(EXPOSED(online)));
|
||||
ADD_UNSIGNED_HEADER("X-UStreamer-Dropped", EXPOSED(dropped));
|
||||
ADD_UNSIGNED_HEADER("X-UStreamer-Width", EXPOSED(width));
|
||||
ADD_UNSIGNED_HEADER("X-UStreamer-Height", EXPOSED(height));
|
||||
ADD_UNSIGNED_HEADER("X-UStreamer-Width", EXPOSED(picture.width));
|
||||
ADD_UNSIGNED_HEADER("X-UStreamer-Height", EXPOSED(picture.height));
|
||||
ADD_TIME_HEADER("X-UStreamer-Grab-Time", EXPOSED(picture.grab_time));
|
||||
ADD_TIME_HEADER("X-UStreamer-Encode-Begin-Time", EXPOSED(picture.encode_begin_time));
|
||||
ADD_TIME_HEADER("X-UStreamer-Encode-End-Time", EXPOSED(picture.encode_end_time));
|
||||
@@ -684,8 +684,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
RN,
|
||||
bool_to_string(EXPOSED(online)),
|
||||
EXPOSED(dropped),
|
||||
EXPOSED(width),
|
||||
EXPOSED(height),
|
||||
EXPOSED(picture.width),
|
||||
EXPOSED(picture.height),
|
||||
client->fps,
|
||||
EXPOSED(picture.grab_time),
|
||||
EXPOSED(picture.encode_begin_time),
|
||||
@@ -823,7 +823,7 @@ static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_serv
|
||||
if (atomic_load(&server->run->stream->updated)) {
|
||||
LOG_DEBUG("Refreshing HTTP exposed ...");
|
||||
A_MUTEX_LOCK(&server->run->stream->mutex);
|
||||
if (server->run->stream->picture.used > 0) { // If online
|
||||
if (server->run->stream->online) {
|
||||
picture_updated = _expose_new_picture_unsafe(server);
|
||||
UNLOCK_STREAM;
|
||||
} else {
|
||||
@@ -846,19 +846,15 @@ static bool _expose_new_picture_unsafe(struct http_server_t *server) {
|
||||
# define STREAM(_next) server->run->stream->_next
|
||||
# define EXPOSED(_next) server->run->exposed->_next
|
||||
|
||||
assert(STREAM(picture.used) > 0);
|
||||
EXPOSED(captured_fps) = STREAM(captured_fps);
|
||||
EXPOSED(expose_begin_time) = get_now_monotonic();
|
||||
|
||||
# define MEM_STREAM_TO_EXPOSED \
|
||||
EXPOSED(picture.data), STREAM(picture.data), STREAM(picture.used)
|
||||
|
||||
if (server->drop_same_frames) {
|
||||
if (
|
||||
EXPOSED(online)
|
||||
&& EXPOSED(dropped) < server->drop_same_frames
|
||||
&& EXPOSED(picture.used) == STREAM(picture.used)
|
||||
&& !memcmp(MEM_STREAM_TO_EXPOSED)
|
||||
&& !memcmp(EXPOSED(picture.data), STREAM(picture.data), STREAM(picture.used))
|
||||
) {
|
||||
EXPOSED(expose_cmp_time) = get_now_monotonic();
|
||||
EXPOSED(expose_end_time) = EXPOSED(expose_cmp_time);
|
||||
@@ -873,23 +869,8 @@ static bool _expose_new_picture_unsafe(struct http_server_t *server) {
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPOSED(picture.allocated) < STREAM(picture.allocated)) {
|
||||
A_REALLOC(EXPOSED(picture.data), STREAM(picture.allocated));
|
||||
EXPOSED(picture.allocated) = STREAM(picture.allocated);
|
||||
}
|
||||
device_copy_picture(&STREAM(picture), &EXPOSED(picture));
|
||||
|
||||
memcpy(MEM_STREAM_TO_EXPOSED);
|
||||
|
||||
# undef MEM_STREAM_TO_EXPOSED
|
||||
|
||||
EXPOSED(picture.used) = STREAM(picture.used);
|
||||
|
||||
EXPOSED(picture.grab_time) = STREAM(picture.grab_time);
|
||||
EXPOSED(picture.encode_begin_time) = STREAM(picture.encode_begin_time);
|
||||
EXPOSED(picture.encode_end_time) = STREAM(picture.encode_end_time);
|
||||
|
||||
EXPOSED(width) = STREAM(width);
|
||||
EXPOSED(height) = STREAM(height);
|
||||
EXPOSED(online) = true;
|
||||
EXPOSED(dropped) = 0;
|
||||
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
|
||||
@@ -904,28 +885,14 @@ static bool _expose_new_picture_unsafe(struct http_server_t *server) {
|
||||
}
|
||||
|
||||
static bool _expose_blank_picture(struct http_server_t *server) {
|
||||
# define BLANK(_next) server->run->blank->_next
|
||||
# define EXPOSED(_next) server->run->exposed->_next
|
||||
|
||||
EXPOSED(expose_begin_time) = get_now_monotonic();
|
||||
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
|
||||
|
||||
if (EXPOSED(online) || EXPOSED(picture.used) == 0) {
|
||||
if (EXPOSED(picture.allocated) < BLANK(picture.used)) {
|
||||
A_REALLOC(EXPOSED(picture.data), BLANK(picture.used));
|
||||
EXPOSED(picture.allocated) = BLANK(picture.used);
|
||||
}
|
||||
device_copy_picture(server->run->blank, &EXPOSED(picture));
|
||||
|
||||
memcpy(EXPOSED(picture.data), BLANK(picture.data), BLANK(picture.used));
|
||||
|
||||
EXPOSED(picture.used) = BLANK(picture.used);
|
||||
|
||||
EXPOSED(picture.grab_time) = 0;
|
||||
EXPOSED(picture.encode_begin_time) = 0;
|
||||
EXPOSED(picture.encode_end_time) = 0;
|
||||
|
||||
EXPOSED(width) = BLANK(width);
|
||||
EXPOSED(height) = BLANK(height);
|
||||
EXPOSED(captured_fps) = 0;
|
||||
EXPOSED(online) = false;
|
||||
goto updated;
|
||||
@@ -944,5 +911,4 @@ static bool _expose_blank_picture(struct http_server_t *server) {
|
||||
return true; // Updated
|
||||
|
||||
# undef EXPOSED
|
||||
# undef BLANK
|
||||
}
|
||||
|
||||
@@ -59,8 +59,6 @@ struct stream_client_t {
|
||||
|
||||
struct exposed_t {
|
||||
struct picture_t picture;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned captured_fps;
|
||||
unsigned queued_fps;
|
||||
bool online;
|
||||
@@ -80,7 +78,7 @@ struct http_server_runtime_t {
|
||||
struct exposed_t *exposed;
|
||||
struct stream_client_t *stream_clients;
|
||||
unsigned stream_clients_count;
|
||||
struct blank_t *blank;
|
||||
struct picture_t *blank;
|
||||
unsigned drop_same_frames_blank;
|
||||
};
|
||||
|
||||
|
||||
23
src/stream.c
23
src/stream.c
@@ -121,6 +121,9 @@ struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
|
||||
|
||||
void stream_destroy(struct stream_t *stream) {
|
||||
A_MUTEX_DESTROY(&stream->mutex);
|
||||
if (stream->picture.data) {
|
||||
free(stream->picture.data);
|
||||
}
|
||||
free(stream->proc);
|
||||
free(stream);
|
||||
}
|
||||
@@ -139,9 +142,6 @@ void stream_loop(struct stream_t *stream) {
|
||||
long long captured_fps_second = 0;
|
||||
bool persistent_timeout_reported = false;
|
||||
|
||||
LOG_DEBUG("Allocation memory for stream picture ...");
|
||||
A_CALLOC(stream->picture.data, stream->dev->run->max_raw_image_size);
|
||||
|
||||
LOG_INFO("Capturing ...");
|
||||
|
||||
while (!atomic_load(&stream->proc->stop)) {
|
||||
@@ -278,10 +278,7 @@ void stream_loop(struct stream_t *stream) {
|
||||
}
|
||||
|
||||
A_MUTEX_LOCK(&stream->mutex);
|
||||
stream->picture.used = 0; // On stream offline
|
||||
free(stream->picture.data);
|
||||
stream->width = 0;
|
||||
stream->height = 0;
|
||||
stream->online = false;
|
||||
atomic_store(&stream->updated, true);
|
||||
A_MUTEX_UNLOCK(&stream->mutex);
|
||||
|
||||
@@ -342,17 +339,9 @@ static void _stream_expose_picture(struct stream_t *stream, unsigned buf_index,
|
||||
|
||||
A_MUTEX_LOCK(&stream->mutex);
|
||||
|
||||
stream->picture.used = PICTURE(used);
|
||||
stream->picture.allocated = PICTURE(allocated);
|
||||
device_copy_picture(&stream->dev->run->pictures[buf_index], &stream->picture);
|
||||
|
||||
memcpy(stream->picture.data, PICTURE(data), stream->picture.used);
|
||||
|
||||
stream->picture.grab_time = PICTURE(grab_time);
|
||||
stream->picture.encode_begin_time = PICTURE(encode_begin_time);
|
||||
stream->picture.encode_end_time = PICTURE(encode_end_time);
|
||||
|
||||
stream->width = stream->dev->run->width;
|
||||
stream->height = stream->dev->run->height;
|
||||
stream->online = true;
|
||||
stream->captured_fps = captured_fps;
|
||||
atomic_store(&stream->updated, true);
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ struct process_t {
|
||||
|
||||
struct stream_t {
|
||||
struct picture_t picture;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool online;
|
||||
unsigned captured_fps;
|
||||
atomic_bool updated;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
Reference in New Issue
Block a user