refactoring

This commit is contained in:
Devaev Maxim
2019-09-12 18:23:45 +03:00
parent b02b0f910c
commit 1d1c7c705d
9 changed files with 70 additions and 95 deletions

View File

@@ -133,6 +133,28 @@ v4l2_std_id device_parse_standard(const char *str) {
return STANDARD_UNKNOWN; 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) { int device_open(struct device_t *dev) {
if ((dev->run->fd = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) { if ((dev->run->fd = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) {
LOG_PERROR("Can't open device"); LOG_PERROR("Can't open device");

View File

@@ -54,6 +54,8 @@ struct picture_t {
unsigned char *data; unsigned char *data;
size_t used; size_t used;
size_t allocated; size_t allocated;
unsigned width;
unsigned height;
long double grab_time; long double grab_time;
long double encode_begin_time; long double encode_begin_time;
long double encode_end_time; long double encode_end_time;
@@ -118,6 +120,8 @@ void device_destroy(struct device_t *dev);
int device_parse_format(const char *str); int device_parse_format(const char *str);
v4l2_std_id device_parse_standard(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); int device_open(struct device_t *dev);
void device_close(struct device_t *dev); void device_close(struct device_t *dev);

View File

@@ -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].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; return 0;
# pragma GCC diagnostic ignored "-Wunused-label" # pragma GCC diagnostic ignored "-Wunused-label"

View File

@@ -31,6 +31,7 @@
#include "../tools.h" #include "../tools.h"
#include "../logging.h" #include "../logging.h"
#include "../device.h"
#include "data/blank_jpeg.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 picture_t *_blank_init_internal(void);
static struct blank_t *_blank_init_external(const char *path); static struct picture_t *_blank_init_external(const char *path);
static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height); static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height);
static void _jpeg_error_handler(j_common_ptr jpeg); static void _jpeg_error_handler(j_common_ptr jpeg);
struct blank_t *blank_init(const char *path) { struct picture_t *blank_init(const char *path) {
struct blank_t *blank = NULL; struct picture_t *blank = NULL;
if (path) { if (path) {
blank = _blank_init_external(path); blank = _blank_init_external(path);
@@ -63,21 +64,21 @@ struct blank_t *blank_init(const char *path) {
return blank; return blank;
} }
void blank_destroy(struct blank_t *blank) { void blank_destroy(struct picture_t *blank) {
free(blank->picture.data); free(blank->data);
free(blank); free(blank);
} }
static struct blank_t *_blank_init_internal(void) { static struct picture_t *_blank_init_internal(void) {
struct blank_t *blank; struct picture_t *blank;
A_CALLOC(blank, 1); A_CALLOC(blank, 1);
A_CALLOC(blank->picture.data, ARRAY_LEN(BLANK_JPEG_DATA)); A_CALLOC(blank->data, ARRAY_LEN(BLANK_JPEG_DATA));
memcpy(blank->picture.data, BLANK_JPEG_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->used = ARRAY_LEN(BLANK_JPEG_DATA);
blank->picture.allocated = ARRAY_LEN(BLANK_JPEG_DATA); blank->allocated = ARRAY_LEN(BLANK_JPEG_DATA);
blank->width = BLANK_JPEG_WIDTH; blank->width = BLANK_JPEG_WIDTH;
blank->height = BLANK_JPEG_HEIGHT; blank->height = BLANK_JPEG_HEIGHT;
@@ -85,9 +86,9 @@ static struct blank_t *_blank_init_internal(void) {
return blank; 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; FILE *fp = NULL;
struct blank_t *blank; struct picture_t *blank;
A_CALLOC(blank, 1); A_CALLOC(blank, 1);
@@ -107,13 +108,13 @@ static struct blank_t *_blank_init_external(const char *path) {
# define CHUNK_SIZE (100 * 1024) # define CHUNK_SIZE (100 * 1024)
while (true) { while (true) {
if (blank->picture.used + CHUNK_SIZE >= blank->picture.allocated) { if (blank->used + CHUNK_SIZE >= blank->allocated) {
blank->picture.allocated = blank->picture.used + CHUNK_SIZE * 2; blank->allocated = blank->used + CHUNK_SIZE * 2;
A_REALLOC(blank->picture.data, blank->picture.allocated); A_REALLOC(blank->data, blank->allocated);
} }
size_t readed = fread(blank->picture.data + blank->picture.used, 1, CHUNK_SIZE, fp); size_t readed = fread(blank->data + blank->used, 1, CHUNK_SIZE, fp);
blank->picture.used += readed; blank->used += readed;
if (readed < CHUNK_SIZE) { if (readed < CHUNK_SIZE) {
if (feof(fp)) { if (feof(fp)) {
@@ -127,7 +128,7 @@ static struct blank_t *_blank_init_external(const char *path) {
# undef CHUNK_SIZE # undef CHUNK_SIZE
error: error:
free(blank->picture.data); free(blank->data);
free(blank); free(blank);
blank = NULL; blank = NULL;

View File

@@ -27,12 +27,5 @@
#include "../device.h" #include "../device.h"
struct blank_t { struct picture_t *blank_init(const char *path);
struct picture_t picture; void blank_destroy(struct picture_t *blank);
unsigned width;
unsigned height;
};
struct blank_t *blank_init(const char *path);
void blank_destroy(struct blank_t *blank);

View File

@@ -436,8 +436,8 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
" \"stream\": {\"queued_fps\": %u, \"clients\": %u, \"clients_stat\": {", " \"stream\": {\"queued_fps\": %u, \"clients\": %u, \"clients_stat\": {",
encoder_type_to_string(encoder_run_type), encoder_type_to_string(encoder_run_type),
encoder_run_quality, encoder_run_quality,
(server->fake_width ? server->fake_width : server->run->exposed->width), (server->fake_width ? server->fake_width : server->run->exposed->picture.width),
(server->fake_height ? server->fake_height : server->run->exposed->height), (server->fake_height ? server->fake_height : server->run->exposed->picture.height),
bool_to_string(server->run->exposed->online), bool_to_string(server->run->exposed->online),
server->run->stream->dev->desired_fps, server->run->stream->dev->desired_fps,
server->run->exposed->captured_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_HEADER("X-UStreamer-Online", bool_to_string(EXPOSED(online)));
ADD_UNSIGNED_HEADER("X-UStreamer-Dropped", EXPOSED(dropped)); ADD_UNSIGNED_HEADER("X-UStreamer-Dropped", EXPOSED(dropped));
ADD_UNSIGNED_HEADER("X-UStreamer-Width", EXPOSED(width)); ADD_UNSIGNED_HEADER("X-UStreamer-Width", EXPOSED(picture.width));
ADD_UNSIGNED_HEADER("X-UStreamer-Height", EXPOSED(height)); 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-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-Begin-Time", EXPOSED(picture.encode_begin_time));
ADD_TIME_HEADER("X-UStreamer-Encode-End-Time", EXPOSED(picture.encode_end_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, RN,
bool_to_string(EXPOSED(online)), bool_to_string(EXPOSED(online)),
EXPOSED(dropped), EXPOSED(dropped),
EXPOSED(width), EXPOSED(picture.width),
EXPOSED(height), EXPOSED(picture.height),
client->fps, client->fps,
EXPOSED(picture.grab_time), EXPOSED(picture.grab_time),
EXPOSED(picture.encode_begin_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)) { if (atomic_load(&server->run->stream->updated)) {
LOG_DEBUG("Refreshing HTTP exposed ..."); LOG_DEBUG("Refreshing HTTP exposed ...");
A_MUTEX_LOCK(&server->run->stream->mutex); 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); picture_updated = _expose_new_picture_unsafe(server);
UNLOCK_STREAM; UNLOCK_STREAM;
} else { } else {
@@ -846,19 +846,15 @@ static bool _expose_new_picture_unsafe(struct http_server_t *server) {
# define STREAM(_next) server->run->stream->_next # define STREAM(_next) server->run->stream->_next
# define EXPOSED(_next) server->run->exposed->_next # define EXPOSED(_next) server->run->exposed->_next
assert(STREAM(picture.used) > 0);
EXPOSED(captured_fps) = STREAM(captured_fps); EXPOSED(captured_fps) = STREAM(captured_fps);
EXPOSED(expose_begin_time) = get_now_monotonic(); 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 (server->drop_same_frames) {
if ( if (
EXPOSED(online) EXPOSED(online)
&& EXPOSED(dropped) < server->drop_same_frames && EXPOSED(dropped) < server->drop_same_frames
&& EXPOSED(picture.used) == STREAM(picture.used) && 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_cmp_time) = get_now_monotonic();
EXPOSED(expose_end_time) = EXPOSED(expose_cmp_time); 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)) { device_copy_picture(&STREAM(picture), &EXPOSED(picture));
A_REALLOC(EXPOSED(picture.data), STREAM(picture.allocated));
EXPOSED(picture.allocated) = STREAM(picture.allocated);
}
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(online) = true;
EXPOSED(dropped) = 0; EXPOSED(dropped) = 0;
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time); 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) { static bool _expose_blank_picture(struct http_server_t *server) {
# define BLANK(_next) server->run->blank->_next
# define EXPOSED(_next) server->run->exposed->_next # define EXPOSED(_next) server->run->exposed->_next
EXPOSED(expose_begin_time) = get_now_monotonic(); EXPOSED(expose_begin_time) = get_now_monotonic();
EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time); EXPOSED(expose_cmp_time) = EXPOSED(expose_begin_time);
if (EXPOSED(online) || EXPOSED(picture.used) == 0) { if (EXPOSED(online) || EXPOSED(picture.used) == 0) {
if (EXPOSED(picture.allocated) < BLANK(picture.used)) { device_copy_picture(server->run->blank, &EXPOSED(picture));
A_REALLOC(EXPOSED(picture.data), BLANK(picture.used));
EXPOSED(picture.allocated) = BLANK(picture.used);
}
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(captured_fps) = 0;
EXPOSED(online) = false; EXPOSED(online) = false;
goto updated; goto updated;
@@ -944,5 +911,4 @@ static bool _expose_blank_picture(struct http_server_t *server) {
return true; // Updated return true; // Updated
# undef EXPOSED # undef EXPOSED
# undef BLANK
} }

View File

@@ -59,8 +59,6 @@ struct stream_client_t {
struct exposed_t { struct exposed_t {
struct picture_t picture; struct picture_t picture;
unsigned width;
unsigned height;
unsigned captured_fps; unsigned captured_fps;
unsigned queued_fps; unsigned queued_fps;
bool online; bool online;
@@ -80,7 +78,7 @@ struct http_server_runtime_t {
struct exposed_t *exposed; struct exposed_t *exposed;
struct stream_client_t *stream_clients; struct stream_client_t *stream_clients;
unsigned stream_clients_count; unsigned stream_clients_count;
struct blank_t *blank; struct picture_t *blank;
unsigned drop_same_frames_blank; unsigned drop_same_frames_blank;
}; };

View File

@@ -121,6 +121,9 @@ struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
void stream_destroy(struct stream_t *stream) { void stream_destroy(struct stream_t *stream) {
A_MUTEX_DESTROY(&stream->mutex); A_MUTEX_DESTROY(&stream->mutex);
if (stream->picture.data) {
free(stream->picture.data);
}
free(stream->proc); free(stream->proc);
free(stream); free(stream);
} }
@@ -139,9 +142,6 @@ void stream_loop(struct stream_t *stream) {
long long captured_fps_second = 0; long long captured_fps_second = 0;
bool persistent_timeout_reported = false; 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 ..."); LOG_INFO("Capturing ...");
while (!atomic_load(&stream->proc->stop)) { while (!atomic_load(&stream->proc->stop)) {
@@ -278,10 +278,7 @@ void stream_loop(struct stream_t *stream) {
} }
A_MUTEX_LOCK(&stream->mutex); A_MUTEX_LOCK(&stream->mutex);
stream->picture.used = 0; // On stream offline stream->online = false;
free(stream->picture.data);
stream->width = 0;
stream->height = 0;
atomic_store(&stream->updated, true); atomic_store(&stream->updated, true);
A_MUTEX_UNLOCK(&stream->mutex); 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); A_MUTEX_LOCK(&stream->mutex);
stream->picture.used = PICTURE(used); device_copy_picture(&stream->dev->run->pictures[buf_index], &stream->picture);
stream->picture.allocated = PICTURE(allocated);
memcpy(stream->picture.data, PICTURE(data), stream->picture.used); stream->online = true;
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->captured_fps = captured_fps; stream->captured_fps = captured_fps;
atomic_store(&stream->updated, true); atomic_store(&stream->updated, true);

View File

@@ -35,8 +35,7 @@ struct process_t {
struct stream_t { struct stream_t {
struct picture_t picture; struct picture_t picture;
unsigned width; bool online;
unsigned height;
unsigned captured_fps; unsigned captured_fps;
atomic_bool updated; atomic_bool updated;
pthread_mutex_t mutex; pthread_mutex_t mutex;