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;
}
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");

View File

@@ -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);

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].width = dev->run->width;
dev->run->pictures[buf_index].height = dev->run->height;
return 0;
# pragma GCC diagnostic ignored "-Wunused-label"

View File

@@ -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;

View File

@@ -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);

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\": {",
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
}

View File

@@ -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;
};

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) {
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);

View File

@@ -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;