refactoring

This commit is contained in:
Devaev Maxim
2020-12-10 12:36:35 +03:00
parent f943f5927c
commit 7225857fcc
25 changed files with 429 additions and 444 deletions

View File

@@ -26,8 +26,8 @@
static int _sem_wait_monotonic(sem_t *sem, long double timeout);
struct rawsink_t *rawsink_init(const char *name, mode_t mode, bool rm, bool master) {
struct rawsink_t *rawsink;
rawsink_s *rawsink_init(const char *name, mode_t mode, bool rm, bool master) {
rawsink_s *rawsink;
int flags = (master ? O_RDWR | O_CREAT : O_RDWR);
A_CALLOC(rawsink, 1);
@@ -66,14 +66,14 @@ struct rawsink_t *rawsink_init(const char *name, mode_t mode, bool rm, bool mast
goto error;
}
if (ftruncate(rawsink->fd, sizeof(struct rawsink_shared_t)) < 0) {
if (ftruncate(rawsink->fd, sizeof(rawsink_shared_s)) < 0) {
LOG_PERROR("Can't truncate RAW sink memory");
goto error;
}
if ((rawsink->shared = mmap(
NULL,
sizeof(struct rawsink_shared_t),
sizeof(rawsink_shared_s),
PROT_READ | PROT_WRITE,
MAP_SHARED,
rawsink->fd,
@@ -98,7 +98,7 @@ struct rawsink_t *rawsink_init(const char *name, mode_t mode, bool rm, bool mast
return NULL;
}
void rawsink_destroy(struct rawsink_t *rawsink) {
void rawsink_destroy(rawsink_s *rawsink) {
# define CLOSE_SEM(_role) { \
if (rawsink->_role##_sem != SEM_FAILED) { \
if (sem_close(rawsink->_role##_sem) < 0) { \
@@ -118,7 +118,7 @@ void rawsink_destroy(struct rawsink_t *rawsink) {
# undef CLOSE_SEM
if (rawsink->shared != MAP_FAILED) {
if (munmap(rawsink->shared, sizeof(struct rawsink_shared_t)) < 0) {
if (munmap(rawsink->shared, sizeof(rawsink_shared_s)) < 0) {
LOG_PERROR("Can't unmap RAW sink memory");
}
}
@@ -141,7 +141,7 @@ void rawsink_destroy(struct rawsink_t *rawsink) {
}
void rawsink_put(
struct rawsink_t *rawsink,
rawsink_s *rawsink,
const uint8_t *data, size_t size,
unsigned format, unsigned width, unsigned height,
long double grab_ts) {
@@ -202,7 +202,7 @@ void rawsink_put(
}
int rawsink_get(
struct rawsink_t *rawsink,
rawsink_s *rawsink,
char *data, size_t *size,
unsigned *format, unsigned *width, unsigned *height,
long double *grab_ts,

View File

@@ -44,22 +44,22 @@
#define RAWSINK_MAX_DATA ((size_t)(CFG_RAWSINK_MAX_DATA))
struct rawsink_shared_t {
typedef struct {
unsigned format;
unsigned width;
unsigned height;
long double grab_ts;
size_t size;
uint8_t data[RAWSINK_MAX_DATA];
};
} rawsink_shared_s;
struct rawsink_t {
typedef struct {
char *mem_name;
char *signal_name;
char *lock_name;
int fd;
struct rawsink_shared_t *shared;
rawsink_shared_s *shared;
sem_t *signal_sem;
sem_t *lock_sem;
@@ -68,20 +68,20 @@ struct rawsink_t {
bool master;
bool master_failed;
};
} rawsink_s;
struct rawsink_t *rawsink_init(const char *name, mode_t mode, bool rm, bool master);
void rawsink_destroy(struct rawsink_t *rawsink);
rawsink_s *rawsink_init(const char *name, mode_t mode, bool rm, bool master);
void rawsink_destroy(rawsink_s *rawsink);
void rawsink_put(
struct rawsink_t *rawsink,
rawsink_s *rawsink,
const uint8_t *data, size_t size,
unsigned format, unsigned witdh, unsigned height,
long double grab_ts);
int rawsink_get(
struct rawsink_t *rawsink,
rawsink_s *rawsink,
char *data, size_t *size,
unsigned *format, unsigned *width, unsigned *height,
long double *grab_ts,

View File

@@ -23,21 +23,21 @@
#include "blank.h"
struct _jpeg_error_manager_t {
typedef struct {
struct jpeg_error_mgr mgr; // Default manager
jmp_buf jmp;
};
} _jpeg_error_manager_s;
static struct frame_t *_init_internal(void);
static struct frame_t *_init_external(const char *path);
static frame_s *_init_internal(void);
static frame_s *_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 frame_t *blank_frame_init(const char *path) {
struct frame_t *blank = NULL;
frame_s *blank_frame_init(const char *path) {
frame_s *blank = NULL;
if (path && path[0] != '\0') {
blank = _init_external(path);
@@ -52,8 +52,8 @@ struct frame_t *blank_frame_init(const char *path) {
return blank;
}
static struct frame_t *_init_internal(void) {
struct frame_t *blank;
static frame_s *_init_internal(void) {
frame_s *blank;
blank = frame_init("blank_internal");
frame_set_data(blank, BLANK_JPEG_DATA, BLANK_JPEG_DATA_SIZE);
@@ -62,9 +62,9 @@ static struct frame_t *_init_internal(void) {
return blank;
}
static struct frame_t *_init_external(const char *path) {
static frame_s *_init_external(const char *path) {
FILE *fp = NULL;
struct frame_t *blank;
frame_s *blank;
blank = frame_init("blank_external");
@@ -116,7 +116,7 @@ static struct frame_t *_init_external(const char *path) {
static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height) {
struct jpeg_decompress_struct jpeg;
struct _jpeg_error_manager_t jpeg_error;
_jpeg_error_manager_s jpeg_error;
jpeg_create_decompress(&jpeg);
@@ -140,7 +140,7 @@ static int _jpeg_read_geometry(FILE *fp, unsigned *width, unsigned *height) {
}
static void _jpeg_error_handler(j_common_ptr jpeg) {
struct _jpeg_error_manager_t *jpeg_error = (struct _jpeg_error_manager_t *)jpeg->err;
_jpeg_error_manager_s *jpeg_error = (_jpeg_error_manager_s *)jpeg->err;
char msg[JMSG_LENGTH_MAX];
(*jpeg_error->mgr.format_message)(jpeg, msg);

View File

@@ -35,4 +35,4 @@
#include "data/blank_jpeg.h"
struct frame_t *blank_frame_init(const char *path);
frame_s *blank_frame_init(const char *path);

View File

@@ -54,23 +54,23 @@ static const struct {
};
static int _device_open_check_cap(struct device_t *dev);
static int _device_open_dv_timings(struct device_t *dev);
static int _device_apply_dv_timings(struct device_t *dev);
static int _device_open_format(struct device_t *dev);
static void _device_open_hw_fps(struct device_t *dev);
static int _device_open_io_method(struct device_t *dev);
static int _device_open_io_method_mmap(struct device_t *dev);
static int _device_open_io_method_userptr(struct device_t *dev);
static int _device_open_queue_buffers(struct device_t *dev);
static int _device_apply_resolution(struct device_t *dev, unsigned width, unsigned height);
static int _device_open_check_cap(device_s *dev);
static int _device_open_dv_timings(device_s *dev);
static int _device_apply_dv_timings(device_s *dev);
static int _device_open_format(device_s *dev);
static void _device_open_hw_fps(device_s *dev);
static int _device_open_io_method(device_s *dev);
static int _device_open_io_method_mmap(device_s *dev);
static int _device_open_io_method_userptr(device_s *dev);
static int _device_open_queue_buffers(device_s *dev);
static int _device_apply_resolution(device_s *dev, unsigned width, unsigned height);
static void _device_apply_controls(struct device_t *dev);
static void _device_apply_controls(device_s *dev);
static int _device_query_control(
struct device_t *dev, struct v4l2_queryctrl *query,
device_s *dev, struct v4l2_queryctrl *query,
const char *name, unsigned cid, bool quiet);
static void _device_set_control(
struct device_t *dev, struct v4l2_queryctrl *query,
device_s *dev, struct v4l2_queryctrl *query,
const char *name, unsigned cid, int value, bool quiet);
static const char *_format_to_string_fourcc(char *buf, size_t size, unsigned format);
@@ -83,9 +83,9 @@ static const char *_io_method_to_string_supported(enum v4l2_memory io_method);
#define RUN(_next) dev->run->_next
struct device_t *device_init(void) {
struct device_runtime_t *run;
struct device_t *dev;
device_s *device_init(void) {
device_runtime_s *run;
device_s *dev;
A_CALLOC(run, 1);
run->fd = -1;
@@ -104,7 +104,7 @@ struct device_t *device_init(void) {
return dev;
}
void device_destroy(struct device_t *dev) {
void device_destroy(device_s *dev) {
free(dev->run);
free(dev);
}
@@ -136,7 +136,7 @@ int device_parse_io_method(const char *str) {
return IO_METHOD_UNKNOWN;
}
int device_open(struct device_t *dev) {
int device_open(device_s *dev) {
if ((RUN(fd) = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) {
LOG_PERROR("Can't open device");
goto error;
@@ -169,7 +169,7 @@ int device_open(struct device_t *dev) {
return -1;
}
void device_close(struct device_t *dev) {
void device_close(device_s *dev) {
RUN(persistent_timeout_reported) = false;
if (RUN(hw_buffers)) {
@@ -208,7 +208,7 @@ void device_close(struct device_t *dev) {
}
}
int device_switch_capturing(struct device_t *dev, bool enable) {
int device_switch_capturing(device_s *dev, bool enable) {
if (enable != RUN(capturing)) {
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -226,7 +226,7 @@ int device_switch_capturing(struct device_t *dev, bool enable) {
return 0;
}
int device_select(struct device_t *dev, bool *has_read, bool *has_write, bool *has_error) {
int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_error) {
struct timeval timeout;
int retval;
@@ -272,7 +272,7 @@ int device_select(struct device_t *dev, bool *has_read, bool *has_write, bool *h
return retval;
}
int device_grab_buffer(struct device_t *dev) {
int device_grab_buffer(device_s *dev) {
struct v4l2_buffer buf_info;
MEMSET_ZERO(buf_info);
@@ -332,7 +332,7 @@ int device_grab_buffer(struct device_t *dev) {
return buf_info.index;
}
int device_release_buffer(struct device_t *dev, unsigned index) {
int device_release_buffer(device_s *dev, unsigned index) {
# define HW(_next) RUN(hw_buffers)[index]._next
LOG_DEBUG("Releasing device buffer index=%u ...", index);
@@ -350,7 +350,7 @@ int device_release_buffer(struct device_t *dev, unsigned index) {
return 0;
}
int device_consume_event(struct device_t *dev) {
int device_consume_event(device_s *dev) {
struct v4l2_event event;
LOG_DEBUG("Calling ioctl(VIDIOC_DQEVENT) ...");
@@ -369,7 +369,7 @@ int device_consume_event(struct device_t *dev) {
return 0;
}
static int _device_open_check_cap(struct device_t *dev) {
static int _device_open_check_cap(device_s *dev) {
struct v4l2_capability cap;
int input = dev->input; // Needs pointer to int for ioctl()
@@ -409,7 +409,7 @@ static int _device_open_check_cap(struct device_t *dev) {
return 0;
}
static int _device_open_dv_timings(struct device_t *dev) {
static int _device_open_dv_timings(device_s *dev) {
_device_apply_resolution(dev, dev->width, dev->height);
if (dev->dv_timings) {
LOG_DEBUG("Using DV timings");
@@ -432,7 +432,7 @@ static int _device_open_dv_timings(struct device_t *dev) {
return 0;
}
static int _device_apply_dv_timings(struct device_t *dev) {
static int _device_apply_dv_timings(device_s *dev) {
struct v4l2_dv_timings dv;
MEMSET_ZERO(dv);
@@ -465,7 +465,7 @@ static int _device_apply_dv_timings(struct device_t *dev) {
return 0;
}
static int _device_open_format(struct device_t *dev) {
static int _device_open_format(device_s *dev) {
struct v4l2_format fmt;
MEMSET_ZERO(fmt);
@@ -517,7 +517,7 @@ static int _device_open_format(struct device_t *dev) {
return 0;
}
static void _device_open_hw_fps(struct device_t *dev) {
static void _device_open_hw_fps(device_s *dev) {
struct v4l2_streamparm setfps;
RUN(hw_fps) = 0;
@@ -572,7 +572,7 @@ static void _device_open_hw_fps(struct device_t *dev) {
# undef SETFPS_TPF
}
static int _device_open_io_method(struct device_t *dev) {
static int _device_open_io_method(device_s *dev) {
LOG_INFO("Using IO method: %s", _io_method_to_string_supported(dev->io_method));
switch (dev->io_method) {
case V4L2_MEMORY_MMAP: return _device_open_io_method_mmap(dev);
@@ -582,7 +582,7 @@ static int _device_open_io_method(struct device_t *dev) {
return -1;
}
static int _device_open_io_method_mmap(struct device_t *dev) {
static int _device_open_io_method_mmap(device_s *dev) {
struct v4l2_requestbuffers req;
MEMSET_ZERO(req);
@@ -643,7 +643,7 @@ static int _device_open_io_method_mmap(struct device_t *dev) {
return 0;
}
static int _device_open_io_method_userptr(struct device_t *dev) {
static int _device_open_io_method_userptr(device_s *dev) {
struct v4l2_requestbuffers req;
unsigned page_size = getpagesize();
unsigned buf_size = align_size(RUN(raw_size), page_size);
@@ -681,7 +681,7 @@ static int _device_open_io_method_userptr(struct device_t *dev) {
return 0;
}
static int _device_open_queue_buffers(struct device_t *dev) {
static int _device_open_queue_buffers(device_s *dev) {
for (unsigned index = 0; index < RUN(n_buffers); ++index) {
struct v4l2_buffer buf_info;
@@ -703,7 +703,7 @@ static int _device_open_queue_buffers(struct device_t *dev) {
return 0;
}
static int _device_apply_resolution(struct device_t *dev, unsigned width, unsigned height) {
static int _device_apply_resolution(device_s *dev, unsigned width, unsigned height) {
// Тут VIDEO_MIN_* не используются из-за странностей минимального разрешения при отсутствии сигнала
// у некоторых устройств, например Auvidea B101
if (
@@ -719,7 +719,7 @@ static int _device_apply_resolution(struct device_t *dev, unsigned width, unsign
return 0;
}
static void _device_apply_controls(struct device_t *dev) {
static void _device_apply_controls(device_s *dev) {
# define SET_CID_VALUE(_cid, _field, _value, _quiet) { \
struct v4l2_queryctrl query; \
if (_device_query_control(dev, &query, #_field, _cid, _quiet) == 0) { \
@@ -775,7 +775,7 @@ static void _device_apply_controls(struct device_t *dev) {
}
static int _device_query_control(
struct device_t *dev, struct v4l2_queryctrl *query,
device_s *dev, struct v4l2_queryctrl *query,
const char *name, unsigned cid, bool quiet) {
// cppcheck-suppress redundantPointerOp
@@ -792,7 +792,7 @@ static int _device_query_control(
}
static void _device_set_control(
struct device_t *dev, struct v4l2_queryctrl *query,
device_s *dev, struct v4l2_queryctrl *query,
const char *name, unsigned cid, int value, bool quiet) {
struct v4l2_control ctl;

View File

@@ -70,7 +70,7 @@
#define IO_METHODS_STR "MMAP, USERPTR"
struct hw_buffer_t {
typedef struct {
uint8_t *data;
size_t used;
size_t allocated;
@@ -79,85 +79,85 @@ struct hw_buffer_t {
unsigned format;
long double grab_ts;
struct v4l2_buffer buf_info;
struct v4l2_buffer buf_info;
pthread_mutex_t grabbed_mutex;
bool grabbed;
};
} hw_buffer_s;
struct device_runtime_t {
int fd;
unsigned width;
unsigned height;
unsigned format;
unsigned hw_fps;
size_t raw_size;
unsigned n_buffers;
struct hw_buffer_t *hw_buffers;
bool capturing;
bool persistent_timeout_reported;
};
typedef struct {
int fd;
unsigned width;
unsigned height;
unsigned format;
unsigned hw_fps;
size_t raw_size;
unsigned n_buffers;
hw_buffer_s *hw_buffers;
bool capturing;
bool persistent_timeout_reported;
} device_runtime_s;
enum control_mode_t {
typedef enum {
CTL_MODE_NONE = 0,
CTL_MODE_VALUE,
CTL_MODE_AUTO,
CTL_MODE_DEFAULT,
};
} control_mode_e;
struct control_t {
enum control_mode_t mode;
int value;
};
typedef struct {
control_mode_e mode;
int value;
} control_s;
struct controls_t {
struct control_t brightness;
struct control_t contrast;
struct control_t saturation;
struct control_t hue;
struct control_t gamma;
struct control_t sharpness;
struct control_t backlight_compensation;
struct control_t white_balance;
struct control_t gain;
struct control_t color_effect;
struct control_t flip_vertical;
struct control_t flip_horizontal;
};
typedef struct {
control_s brightness;
control_s contrast;
control_s saturation;
control_s hue;
control_s gamma;
control_s sharpness;
control_s backlight_compensation;
control_s white_balance;
control_s gain;
control_s color_effect;
control_s flip_vertical;
control_s flip_horizontal;
} controls_s;
struct device_t {
char *path;
unsigned input;
unsigned width;
unsigned height;
unsigned format;
v4l2_std_id standard;
typedef struct {
char *path;
unsigned input;
unsigned width;
unsigned height;
unsigned format;
v4l2_std_id standard;
enum v4l2_memory io_method;
bool dv_timings;
unsigned n_buffers;
unsigned desired_fps;
size_t min_frame_size;
bool persistent;
unsigned timeout;
bool dv_timings;
unsigned n_buffers;
unsigned desired_fps;
size_t min_frame_size;
bool persistent;
unsigned timeout;
struct controls_t ctl;
controls_s ctl;
struct device_runtime_t *run;
};
device_runtime_s *run;
} device_s;
struct device_t *device_init(void);
void device_destroy(struct device_t *dev);
device_s *device_init(void);
void device_destroy(device_s *dev);
int device_parse_format(const char *str);
v4l2_std_id device_parse_standard(const char *str);
int device_parse_io_method(const char *str);
int device_open(struct device_t *dev);
void device_close(struct device_t *dev);
int device_open(device_s *dev);
void device_close(device_s *dev);
int device_switch_capturing(struct device_t *dev, bool enable);
int device_select(struct device_t *dev, bool *has_read, bool *has_write, bool *has_error);
int device_grab_buffer(struct device_t *dev);
int device_release_buffer(struct device_t *dev, unsigned index);
int device_consume_event(struct device_t *dev);
int device_switch_capturing(device_s *dev, bool enable);
int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_error);
int device_grab_buffer(device_s *dev);
int device_release_buffer(device_s *dev, unsigned index);
int device_consume_event(device_s *dev);

View File

@@ -25,7 +25,7 @@
static const struct {
const char *name;
const enum encoder_type_t type;
const encoder_type_e type;
} _ENCODER_TYPES[] = {
{"CPU", ENCODER_TYPE_CPU},
{"HW", ENCODER_TYPE_HW},
@@ -42,9 +42,9 @@ static const struct {
#define DR(_next) dev->run->_next
struct encoder_t *encoder_init(void) {
struct encoder_runtime_t *run;
struct encoder_t *encoder;
encoder_s *encoder_init(void) {
encoder_runtime_s *run;
encoder_s *encoder;
A_CALLOC(run, 1);
run->type = ENCODER_TYPE_CPU;
@@ -59,7 +59,7 @@ struct encoder_t *encoder_init(void) {
return encoder;
}
void encoder_destroy(struct encoder_t *encoder) {
void encoder_destroy(encoder_s *encoder) {
# ifdef WITH_OMX
if (ER(omxs)) {
for (unsigned index = 0; index < ER(n_omxs); ++index) {
@@ -75,7 +75,7 @@ void encoder_destroy(struct encoder_t *encoder) {
free(encoder);
}
enum encoder_type_t encoder_parse_type(const char *str) {
encoder_type_e encoder_parse_type(const char *str) {
for (unsigned index = 0; index < ARRAY_LEN(_ENCODER_TYPES); ++index) {
if (!strcasecmp(str, _ENCODER_TYPES[index].name)) {
return _ENCODER_TYPES[index].type;
@@ -84,7 +84,7 @@ enum encoder_type_t encoder_parse_type(const char *str) {
return ENCODER_TYPE_UNKNOWN;
}
const char *encoder_type_to_string(enum encoder_type_t type) {
const char *encoder_type_to_string(encoder_type_e type) {
for (unsigned index = 0; index < ARRAY_LEN(_ENCODER_TYPES); ++index) {
if (_ENCODER_TYPES[index].type == type) {
return _ENCODER_TYPES[index].name;
@@ -93,8 +93,8 @@ const char *encoder_type_to_string(enum encoder_type_t type) {
return _ENCODER_TYPES[0].name;
}
void encoder_prepare(struct encoder_t *encoder, struct device_t *dev) {
enum encoder_type_t type = (ER(cpu_forced) ? ENCODER_TYPE_CPU : encoder->type);
void encoder_prepare(encoder_s *encoder, device_s *dev) {
encoder_type_e type = (ER(cpu_forced) ? ENCODER_TYPE_CPU : encoder->type);
unsigned quality = encoder->quality;
bool cpu_forced = false;
@@ -198,7 +198,7 @@ void encoder_prepare(struct encoder_t *encoder, struct device_t *dev) {
A_MUTEX_UNLOCK(&ER(mutex));
}
void encoder_get_runtime_params(struct encoder_t *encoder, enum encoder_type_t *type, unsigned *quality) {
void encoder_get_runtime_params(encoder_s *encoder, encoder_type_e *type, unsigned *quality) {
A_MUTEX_LOCK(&ER(mutex));
*type = ER(type);
*quality = ER(quality);
@@ -207,9 +207,7 @@ void encoder_get_runtime_params(struct encoder_t *encoder, enum encoder_type_t *
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic push
int encoder_compress_buffer(
struct encoder_t *encoder, unsigned worker_number,
struct hw_buffer_t *hw, struct frame_t *frame) {
int encoder_compress_buffer(encoder_s *encoder, unsigned worker_number, hw_buffer_s *hw, frame_s *frame) {
#pragma GCC diagnostic pop
assert(ER(type) != ENCODER_TYPE_UNKNOWN);

View File

@@ -63,7 +63,7 @@
ENCODER_TYPES_OMX_HINT \
ENCODER_TYPES_NOOP_HINT
enum encoder_type_t {
typedef enum {
ENCODER_TYPE_UNKNOWN, // Only for encoder_parse_type() and main()
ENCODER_TYPE_CPU,
ENCODER_TYPE_HW,
@@ -73,44 +73,42 @@ enum encoder_type_t {
# ifdef WITH_RAWSINK
ENCODER_TYPE_NOOP,
# endif
};
} encoder_type_e;
struct encoder_runtime_t {
enum encoder_type_t type;
unsigned quality;
bool cpu_forced;
pthread_mutex_t mutex;
typedef struct {
encoder_type_e type;
unsigned quality;
bool cpu_forced;
pthread_mutex_t mutex;
unsigned n_workers;
unsigned n_workers;
# ifdef WITH_OMX
unsigned n_omxs;
struct omx_encoder_t **omxs;
omx_encoder_s **omxs;
# endif
};
} encoder_runtime_s;
struct encoder_t {
enum encoder_type_t type;
unsigned quality;
unsigned n_workers;
typedef struct {
encoder_type_e type;
unsigned quality;
unsigned n_workers;
# ifdef WITH_OMX
unsigned n_glitched_resolutions;
unsigned glitched_resolutions[2][MAX_GLITCHED_RESOLUTIONS];
# endif
struct encoder_runtime_t *run;
};
encoder_runtime_s *run;
} encoder_s;
struct encoder_t *encoder_init(void);
void encoder_destroy(struct encoder_t *encoder);
encoder_s *encoder_init(void);
void encoder_destroy(encoder_s *encoder);
enum encoder_type_t encoder_parse_type(const char *str);
const char *encoder_type_to_string(enum encoder_type_t type);
encoder_type_e encoder_parse_type(const char *str);
const char *encoder_type_to_string(encoder_type_e type);
void encoder_prepare(struct encoder_t *encoder, struct device_t *dev);
void encoder_get_runtime_params(struct encoder_t *encoder, enum encoder_type_t *type, unsigned *quality);
void encoder_prepare(encoder_s *encoder, device_s *dev);
void encoder_get_runtime_params(encoder_s *encoder, encoder_type_e *type, unsigned *quality);
int encoder_compress_buffer(
struct encoder_t *encoder, unsigned worker_number,
struct hw_buffer_t *hw, struct frame_t *frame);
int encoder_compress_buffer(encoder_s *encoder, unsigned worker_number, hw_buffer_s *hw, frame_s *frame);

View File

@@ -28,14 +28,14 @@
#include "encoder.h"
struct _jpeg_dest_manager_t {
struct jpeg_destination_mgr mgr; // Default manager
JOCTET *buffer; // Start of buffer
struct frame_t *frame;
};
typedef struct {
struct jpeg_destination_mgr mgr; // Default manager
JOCTET *buffer; // Start of buffer
frame_s *frame;
} _jpeg_dest_manager_s;
static void _jpeg_set_picture(j_compress_ptr jpeg, struct frame_t *frame);
static void _jpeg_set_picture(j_compress_ptr jpeg, frame_s *frame);
static void _jpeg_write_scanlines_yuyv(
struct jpeg_compress_struct *jpeg, const uint8_t *data,
@@ -58,7 +58,7 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg);
static void _jpeg_term_destination(j_compress_ptr jpeg);
void cpu_encoder_compress_buffer(struct hw_buffer_t *hw, struct frame_t *frame, unsigned quality) {
void cpu_encoder_compress_buffer(hw_buffer_s *hw, frame_s *frame, unsigned quality) {
// This function based on compress_image_to_jpeg() from mjpg-streamer
struct jpeg_compress_struct jpeg;
@@ -99,16 +99,16 @@ void cpu_encoder_compress_buffer(struct hw_buffer_t *hw, struct frame_t *frame,
assert(frame->used > 0);
}
static void _jpeg_set_picture(j_compress_ptr jpeg, struct frame_t *frame) {
struct _jpeg_dest_manager_t *dest;
static void _jpeg_set_picture(j_compress_ptr jpeg, frame_s *frame) {
_jpeg_dest_manager_s *dest;
if (jpeg->dest == NULL) {
assert((jpeg->dest = (struct jpeg_destination_mgr *)(*jpeg->mem->alloc_small)(
(j_common_ptr) jpeg, JPOOL_PERMANENT, sizeof(struct _jpeg_dest_manager_t)
(j_common_ptr) jpeg, JPOOL_PERMANENT, sizeof(_jpeg_dest_manager_s)
)));
}
dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
dest = (_jpeg_dest_manager_s *)jpeg->dest;
dest->mgr.init_destination = _jpeg_init_destination;
dest->mgr.empty_output_buffer = _jpeg_empty_output_buffer;
dest->mgr.term_destination = _jpeg_term_destination;
@@ -249,7 +249,7 @@ static void _jpeg_write_scanlines_rgb24(
#define JPEG_OUTPUT_BUFFER_SIZE ((size_t)4096)
static void _jpeg_init_destination(j_compress_ptr jpeg) {
struct _jpeg_dest_manager_t *dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
// Allocate the output buffer - it will be released when done with image
assert((dest->buffer = (JOCTET *)(*jpeg->mem->alloc_small)(
@@ -263,7 +263,7 @@ static void _jpeg_init_destination(j_compress_ptr jpeg) {
static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg) {
// Called whenever local jpeg buffer fills up
struct _jpeg_dest_manager_t *dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
frame_append_data(dest->frame, dest->buffer, JPEG_OUTPUT_BUFFER_SIZE);
@@ -277,7 +277,7 @@ static void _jpeg_term_destination(j_compress_ptr jpeg) {
// Called by jpeg_finish_compress after all data has been written.
// Usually needs to flush buffer.
struct _jpeg_dest_manager_t *dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
size_t final = JPEG_OUTPUT_BUFFER_SIZE - dest->mgr.free_in_buffer;
// Write any data remaining in the buffer.

View File

@@ -36,4 +36,4 @@
#include "../../device.h"
void cpu_encoder_compress_buffer(struct hw_buffer_t *hw, struct frame_t *frame, unsigned quality);
void cpu_encoder_compress_buffer(hw_buffer_s *hw, frame_s *frame, unsigned quality);

View File

@@ -28,11 +28,11 @@
#include "encoder.h"
void _copy_plus_huffman(const struct hw_buffer_t *src, struct frame_t *dest);
void _copy_plus_huffman(const hw_buffer_s *src, frame_s *dest);
static bool _is_huffman(const uint8_t *data);
int hw_encoder_prepare(struct device_t *dev, unsigned quality) {
int hw_encoder_prepare(device_s *dev, unsigned quality) {
struct v4l2_jpegcompression comp;
MEMSET_ZERO(comp);
@@ -49,14 +49,14 @@ int hw_encoder_prepare(struct device_t *dev, unsigned quality) {
return 0;
}
void hw_encoder_compress_buffer(struct hw_buffer_t *hw, struct frame_t *frame) {
void hw_encoder_compress_buffer(hw_buffer_s *hw, frame_s *frame) {
if (hw->format != V4L2_PIX_FMT_MJPEG && hw->format != V4L2_PIX_FMT_JPEG) {
assert(0 && "Unsupported input format for HW encoder");
}
_copy_plus_huffman(hw, frame);
}
void _copy_plus_huffman(const struct hw_buffer_t *src, struct frame_t *dest) {
void _copy_plus_huffman(const hw_buffer_s *src, frame_s *dest) {
if (!_is_huffman(src->data)) {
const uint8_t *src_ptr = src->data;
const uint8_t *src_end = src->data + src->used;

View File

@@ -38,5 +38,5 @@
#include "huffman.h"
int hw_encoder_prepare(struct device_t *dev, unsigned quality);
void hw_encoder_compress_buffer(struct hw_buffer_t *hw, struct frame_t *frame);
int hw_encoder_prepare(device_s *dev, unsigned quality);
void hw_encoder_compress_buffer(hw_buffer_s *hw, frame_s *frame);

View File

@@ -31,11 +31,11 @@ static int _i_omx = 0;
static int _vcos_semwait(VCOS_SEMAPHORE_T *sem);
static int _omx_init_component(struct omx_encoder_t *omx);
static int _omx_init_disable_ports(struct omx_encoder_t *omx);
static int _omx_setup_input(struct omx_encoder_t *omx, struct device_t *dev);
static int _omx_setup_output(struct omx_encoder_t *omx, unsigned quality);
static int _omx_encoder_clear_ports(struct omx_encoder_t *omx);
static int _omx_init_component(omx_encoder_s *omx);
static int _omx_init_disable_ports(omx_encoder_s *omx);
static int _omx_setup_input(omx_encoder_s *omx, device_s *dev);
static int _omx_setup_output(omx_encoder_s *omx, unsigned quality);
static int _omx_encoder_clear_ports(omx_encoder_s *omx);
static OMX_ERRORTYPE _omx_event_handler(
UNUSED OMX_HANDLETYPE encoder,
@@ -51,7 +51,7 @@ static OMX_ERRORTYPE _omx_output_available_handler(
OMX_PTR v_omx, UNUSED OMX_BUFFERHEADERTYPE *buffer);
struct omx_encoder_t *omx_encoder_init(void) {
omx_encoder_s *omx_encoder_init(void) {
// Some theory:
// - http://www.fourcc.org/yuv.php
// - https://kwasi-ich.de/blog/2017/11/26/omx/
@@ -62,7 +62,7 @@ struct omx_encoder_t *omx_encoder_init(void) {
// - https://bitbucket.org/bensch128/omxjpegencode/src/master/jpeg_encoder.cpp
// - http://home.nouwen.name/RaspberryPi/documentation/ilcomponents/image_encode.html
struct omx_encoder_t *omx;
omx_encoder_s *omx;
OMX_ERRORTYPE error;
A_CALLOC(omx, 1);
@@ -103,7 +103,7 @@ struct omx_encoder_t *omx_encoder_init(void) {
return NULL;
}
void omx_encoder_destroy(struct omx_encoder_t *omx) {
void omx_encoder_destroy(omx_encoder_s *omx) {
OMX_ERRORTYPE error;
LOG_INFO("Destroying OMX encoder ...");
@@ -135,7 +135,7 @@ void omx_encoder_destroy(struct omx_encoder_t *omx) {
free(omx);
}
int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigned quality) {
int omx_encoder_prepare(omx_encoder_s *omx, device_s *dev, unsigned quality) {
if (component_set_state(&omx->encoder, OMX_StateIdle) < 0) {
return -1;
}
@@ -154,7 +154,7 @@ int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigne
return 0;
}
int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct hw_buffer_t *hw, struct frame_t *frame) {
int omx_encoder_compress_buffer(omx_encoder_s *omx, hw_buffer_s *hw, frame_s *frame) {
# define IN(_next) omx->input_buffer->_next
# define OUT(_next) omx->output_buffer->_next
@@ -259,7 +259,7 @@ static int _vcos_semwait(VCOS_SEMAPHORE_T *sem) {
# endif
}
static int _omx_init_component(struct omx_encoder_t *omx) {
static int _omx_init_component(omx_encoder_s *omx) {
OMX_ERRORTYPE error;
OMX_CALLBACKTYPE callbacks;
@@ -277,7 +277,7 @@ static int _omx_init_component(struct omx_encoder_t *omx) {
return 0;
}
static int _omx_init_disable_ports(struct omx_encoder_t *omx) {
static int _omx_init_disable_ports(omx_encoder_s *omx) {
OMX_ERRORTYPE error;
OMX_INDEXTYPE types[] = {
OMX_IndexParamAudioInit, OMX_IndexParamVideoInit,
@@ -305,7 +305,7 @@ static int _omx_init_disable_ports(struct omx_encoder_t *omx) {
return 0;
}
static int _omx_setup_input(struct omx_encoder_t *omx, struct device_t *dev) {
static int _omx_setup_input(omx_encoder_s *omx, device_s *dev) {
OMX_ERRORTYPE error;
OMX_PARAM_PORTDEFINITIONTYPE portdef;
@@ -364,7 +364,7 @@ static int _omx_setup_input(struct omx_encoder_t *omx, struct device_t *dev) {
return 0;
}
static int _omx_setup_output(struct omx_encoder_t *omx, unsigned quality) {
static int _omx_setup_output(omx_encoder_s *omx, unsigned quality) {
OMX_ERRORTYPE error;
OMX_PARAM_PORTDEFINITIONTYPE portdef;
@@ -438,7 +438,7 @@ static int _omx_setup_output(struct omx_encoder_t *omx, unsigned quality) {
return 0;
}
static int _omx_encoder_clear_ports(struct omx_encoder_t *omx) {
static int _omx_encoder_clear_ports(omx_encoder_s *omx) {
OMX_ERRORTYPE error;
int retval = 0;
@@ -475,7 +475,7 @@ static OMX_ERRORTYPE _omx_event_handler(
// OMX calls this handler for all the events it emits
struct omx_encoder_t *omx = (struct omx_encoder_t *)v_omx;
omx_encoder_s *omx = (omx_encoder_s *)v_omx;
if (event == OMX_EventError) {
LOG_ERROR_OMX((OMX_ERRORTYPE)data1, "OMX error event received");
@@ -492,7 +492,7 @@ static OMX_ERRORTYPE _omx_input_required_handler(
// Called by OMX when the encoder component requires
// the input buffer to be filled with RAW image data
struct omx_encoder_t *omx = (struct omx_encoder_t *)v_omx;
omx_encoder_s *omx = (omx_encoder_s *)v_omx;
omx->input_required = true;
assert(vcos_semaphore_post(&omx->handler_sem) == VCOS_SUCCESS);
@@ -506,7 +506,7 @@ static OMX_ERRORTYPE _omx_output_available_handler(
// Called by OMX when the encoder component has filled
// the output buffer with JPEG data
struct omx_encoder_t *omx = (struct omx_encoder_t *)v_omx;
omx_encoder_s *omx = (omx_encoder_s *)v_omx;
omx->output_available = true;
assert(vcos_semaphore_post(&omx->handler_sem) == VCOS_SUCCESS);

View File

@@ -51,7 +51,7 @@
#define OMX_MAX_ENCODERS ((unsigned)(CFG_OMX_MAX_ENCODERS))
struct omx_encoder_t {
typedef struct {
OMX_HANDLETYPE encoder;
OMX_BUFFERHEADERTYPE *input_buffer;
OMX_BUFFERHEADERTYPE *output_buffer;
@@ -64,11 +64,11 @@ struct omx_encoder_t {
bool i_encoder;
bool i_input_port_enabled;
bool i_output_port_enabled;
};
} omx_encoder_s;
struct omx_encoder_t *omx_encoder_init(void);
void omx_encoder_destroy(struct omx_encoder_t *omx);
omx_encoder_s *omx_encoder_init(void);
void omx_encoder_destroy(omx_encoder_s *omx);
int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigned quality);
int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct hw_buffer_t *hw, struct frame_t *frame);
int omx_encoder_prepare(omx_encoder_s *omx, device_s *dev, unsigned quality);
int omx_encoder_compress_buffer(omx_encoder_s *omx, hw_buffer_s *hw, frame_s *frame);

View File

@@ -23,8 +23,8 @@
#include "frame.h"
struct frame_t *frame_init(const char *role) {
struct frame_t *frame;
frame_s *frame_init(const char *role) {
frame_s *frame;
A_CALLOC(frame, 1);
frame->role = role;
@@ -32,14 +32,14 @@ struct frame_t *frame_init(const char *role) {
return frame;
}
void frame_destroy(struct frame_t *frame) {
void frame_destroy(frame_s *frame) {
if (frame->data) {
free(frame->data);
}
free(frame);
}
void frame_realloc_data(struct frame_t *frame, size_t size) {
void frame_realloc_data(frame_s *frame, size_t size) {
if (frame->allocated < size) {
LOG_DEBUG("Increasing frame buffer '%s': %zu -> %zu (+%zu)",
frame->role, frame->allocated, size, size - frame->allocated);
@@ -48,13 +48,13 @@ void frame_realloc_data(struct frame_t *frame, size_t size) {
}
}
void frame_set_data(struct frame_t *frame, const uint8_t *data, size_t size) {
void frame_set_data(frame_s *frame, const uint8_t *data, size_t size) {
frame_realloc_data(frame, size);
memcpy(frame->data, data, size);
frame->used = size;
}
void frame_append_data(struct frame_t *frame, const uint8_t *data, size_t size) {
void frame_append_data(frame_s *frame, const uint8_t *data, size_t size) {
size_t new_used = frame->used + size;
frame_realloc_data(frame, new_used);
@@ -62,7 +62,7 @@ void frame_append_data(struct frame_t *frame, const uint8_t *data, size_t size)
frame->used = new_used;
}
void frame_copy(const struct frame_t *src, struct frame_t *dest) {
void frame_copy(const frame_s *src, frame_s *dest) {
frame_set_data(dest, src->data, src->used);
# define COPY(_field) dest->_field = src->_field
@@ -80,7 +80,7 @@ void frame_copy(const struct frame_t *src, struct frame_t *dest) {
# undef COPY
}
bool frame_compare(const struct frame_t *a, const struct frame_t *b) {
bool frame_compare(const frame_s *a, const frame_s *b) {
return (
a->allocated && b->allocated
&& a->used == b->used

View File

@@ -33,7 +33,7 @@
#include "../common/logging.h"
struct frame_t {
typedef struct {
const char *role;
uint8_t *data;
size_t used;
@@ -43,15 +43,15 @@ struct frame_t {
long double grab_ts;
long double encode_begin_ts;
long double encode_end_ts;
};
} frame_s;
struct frame_t *frame_init(const char *role);
void frame_destroy(struct frame_t *frame);
frame_s *frame_init(const char *role);
void frame_destroy(frame_s *frame);
void frame_realloc_data(struct frame_t *frame, size_t size);
void frame_set_data(struct frame_t *frame, const uint8_t *data, size_t size);
void frame_append_data(struct frame_t *frame, const uint8_t *data, size_t size);
void frame_realloc_data(frame_s *frame, size_t size);
void frame_set_data(frame_s *frame, const uint8_t *data, size_t size);
void frame_append_data(frame_s *frame, const uint8_t *data, size_t size);
void frame_copy(const struct frame_t *src, struct frame_t *dest);
bool frame_compare(const struct frame_t *a, const struct frame_t *b);
void frame_copy(const frame_s *src, frame_s *dest);
bool frame_compare(const frame_s *a, const frame_s *b);

View File

@@ -23,7 +23,7 @@
#include "gpio.h"
struct gpio_t gpio = {
gpio_s gpio = {
.path = "/dev/gpiochip0",
.consumer_prefix = "ustreamer",
@@ -46,8 +46,8 @@ struct gpio_t gpio = {
};
static void _gpio_output_init(struct gpio_output_t *output);
static void _gpio_output_destroy(struct gpio_output_t *output);
static void _gpio_output_init(gpio_output_s *output);
static void _gpio_output_destroy(gpio_output_s *output);
void gpio_init(void) {
@@ -80,7 +80,7 @@ void gpio_destroy(void) {
}
}
int gpio_inner_set(struct gpio_output_t *output, bool state) {
int gpio_inner_set(gpio_output_s *output, bool state) {
int retval = 0;
assert(gpio.chip);
@@ -98,7 +98,7 @@ int gpio_inner_set(struct gpio_output_t *output, bool state) {
return retval;
}
static void _gpio_output_init(struct gpio_output_t *output) {
static void _gpio_output_init(gpio_output_s *output) {
assert(gpio.chip);
assert(output->line == NULL);
@@ -117,7 +117,7 @@ static void _gpio_output_init(struct gpio_output_t *output) {
}
}
static void _gpio_output_destroy(struct gpio_output_t *output) {
static void _gpio_output_destroy(gpio_output_s *output) {
if (output->line) {
gpiod_line_release(output->line);
output->line = NULL;

View File

@@ -35,33 +35,33 @@
#include "../../common/threading.h"
struct gpio_output_t {
typedef struct {
int pin;
const char *role;
char *consumer;
struct gpiod_line *line;
bool state;
};
} gpio_output_s;
struct gpio_t {
typedef struct {
char *path;
char *consumer_prefix;
struct gpio_output_t prog_running;
struct gpio_output_t stream_online;
struct gpio_output_t has_http_clients;
gpio_output_s prog_running;
gpio_output_s stream_online;
gpio_output_s has_http_clients;
pthread_mutex_t mutex;
struct gpiod_chip *chip;
};
} gpio_s;
extern struct gpio_t gpio;
extern gpio_s gpio;
void gpio_init(void);
void gpio_destroy(void);
int gpio_inner_set(struct gpio_output_t *output, bool state);
int gpio_inner_set(gpio_output_s *output, bool state);
#define SET_STATE(_output, _state) { \

View File

@@ -23,7 +23,7 @@
#include "server.h"
static int _http_preprocess_request(struct evhttp_request *request, struct http_server_t *server);
static int _http_preprocess_request(struct evhttp_request *request, server_s *server);
static void _http_callback_root(struct evhttp_request *request, void *v_server);
static void _http_callback_static(struct evhttp_request *request, void *v_server);
@@ -35,9 +35,9 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
static void _http_callback_stream_error(struct bufferevent *buf_event, short what, void *v_ctx);
static void _http_exposed_refresh(int fd, short event, void *v_server);
static void _http_queue_send_stream(struct http_server_t *server, bool stream_updated, bool frame_updated);
static void _http_queue_send_stream(server_s *server, bool stream_updated, bool frame_updated);
static bool _expose_new_frame(struct http_server_t *server);
static bool _expose_new_frame(server_s *server);
static void _format_bufferevent_reason(short what, char *reason);
@@ -47,10 +47,10 @@ static void _format_bufferevent_reason(short what, char *reason);
#define EX(_next) RUN(exposed->_next)
struct http_server_t *http_server_init(struct stream_t *stream) {
struct http_server_runtime_t *run;
struct http_server_t *server;
struct exposed_t *exposed;
server_s *server_init(stream_s *stream) {
server_runtime_s *run;
server_s *server;
exposed_s *exposed;
A_CALLOC(exposed, 1);
exposed->frame = frame_init("http_exposed");
@@ -77,7 +77,7 @@ struct http_server_t *http_server_init(struct stream_t *stream) {
return server;
}
void http_server_destroy(struct http_server_t *server) {
void server_destroy(server_s *server) {
if (RUN(refresh)) {
event_del(RUN(refresh));
event_free(RUN(refresh));
@@ -93,8 +93,8 @@ void http_server_destroy(struct http_server_t *server) {
libevent_global_shutdown();
# endif
for (struct stream_client_t *client = RUN(stream_clients); client != NULL;) {
struct stream_client_t *next = client->next;
for (stream_client_s *client = RUN(stream_clients); client != NULL;) {
stream_client_s *next = client->next;
free(client->key);
free(client);
@@ -111,7 +111,7 @@ void http_server_destroy(struct http_server_t *server) {
free(server);
}
int http_server_listen(struct http_server_t *server) {
int server_listen(server_s *server) {
{
if (server->static_path[0] != '\0') {
LOG_INFO("Enabling HTTP file server: %s", server->static_path);
@@ -193,20 +193,20 @@ int http_server_listen(struct http_server_t *server) {
return 0;
}
void http_server_loop(struct http_server_t *server) {
void server_loop(server_s *server) {
LOG_INFO("Starting HTTP eventloop ...");
event_base_dispatch(RUN(base));
LOG_INFO("HTTP eventloop stopped");
}
void http_server_loop_break(struct http_server_t *server) {
void server_loop_break(server_s *server) {
event_base_loopbreak(RUN(base));
}
#define ADD_HEADER(_key, _value) \
assert(!evhttp_add_header(evhttp_request_get_output_headers(request), _key, _value))
static int _http_preprocess_request(struct evhttp_request *request, struct http_server_t *server) {
static int _http_preprocess_request(struct evhttp_request *request, server_s *server) {
if (RUN(auth_token)) {
const char *token = evhttp_find_header(evhttp_request_get_input_headers(request), "Authorization");
@@ -232,7 +232,7 @@ static int _http_preprocess_request(struct evhttp_request *request, struct http_
}
static void _http_callback_root(struct evhttp_request *request, void *v_server) {
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
struct evbuffer *buf;
struct evkeyvalq params; // For mjpg-streamer compatibility
const char *action; // Ditto
@@ -258,7 +258,7 @@ static void _http_callback_root(struct evhttp_request *request, void *v_server)
}
static void _http_callback_static(struct evhttp_request *request, void *v_server) {
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
struct evbuffer *buf = NULL;
struct evhttp_uri *uri = NULL;
char *uri_path;
@@ -331,9 +331,9 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server
}
static void _http_callback_state(struct evhttp_request *request, void *v_server) {
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
struct evbuffer *buf;
enum encoder_type_t encoder_type;
encoder_type_e encoder_type;
unsigned encoder_quality;
PREPROCESS_REQUEST;
@@ -359,7 +359,7 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
RUN(stream_clients_count)
));
for (struct stream_client_t * client = RUN(stream_clients); client != NULL; client = client->next) {
for (stream_client_s * client = RUN(stream_clients); client != NULL; client = client->next) {
assert(evbuffer_add_printf(buf,
"\"%s\": {\"fps\": %u, \"extra_headers\": %s, \"advance_headers\": %s, \"dual_final_frames\": %s}%s",
client->id,
@@ -379,7 +379,7 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
}
static void _http_callback_snapshot(struct evhttp_request *request, void *v_server) {
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
struct evbuffer *buf;
char header_buf[64];
@@ -437,11 +437,11 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
// https://github.com/libevent/libevent/blob/29cc8386a2f7911eaa9336692a2c5544d8b4734f/http.c#L791
// https://github.com/libevent/libevent/blob/29cc8386a2f7911eaa9336692a2c5544d8b4734f/http.c#L1458
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
struct evhttp_connection *conn;
struct evkeyvalq params;
struct bufferevent *buf_event;
struct stream_client_t *client;
stream_client_s *client;
char *client_addr;
unsigned short client_port;
uuid_t uuid;
@@ -469,7 +469,7 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
if (RUN(stream_clients) == NULL) {
RUN(stream_clients) = client;
} else {
struct stream_client_t *last = RUN(stream_clients);
stream_client_s *last = RUN(stream_clients);
for (; last->next != NULL; last = last->next);
client->prev = last;
@@ -515,8 +515,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
# define BOUNDARY "boundarydonotcross"
# define RN "\r\n"
struct stream_client_t *client = (struct stream_client_t *)v_client;
struct http_server_t *server = client->server;
stream_client_s *client = (stream_client_s *)v_client;
server_s *server = client->server;
struct evbuffer *buf;
long double now = get_now_monotonic();
long long now_second = floor_ms(now);
@@ -638,8 +638,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
}
static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UNUSED short what, void *v_client) {
struct stream_client_t *client = (struct stream_client_t *)v_client;
struct http_server_t *server = client->server;
stream_client_s *client = (stream_client_s *)v_client;
server_s *server = client->server;
struct evhttp_connection *conn;
char *client_addr = "???";
unsigned short client_port = 0;
@@ -683,14 +683,14 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN
free(client);
}
static void _http_queue_send_stream(struct http_server_t *server, bool stream_updated, bool frame_updated) {
static void _http_queue_send_stream(server_s *server, bool stream_updated, bool frame_updated) {
struct evhttp_connection *conn;
struct bufferevent *buf_event;
long long now;
bool has_clients = false;
bool queued = false;
for (struct stream_client_t *client = RUN(stream_clients); client != NULL; client = client->next) {
for (stream_client_s *client = RUN(stream_clients); client != NULL; client = client->next) {
conn = evhttp_request_get_connection(client->request);
if (conn) {
// Фикс для бага WebKit. При включенной опции дропа одинаковых фреймов,
@@ -739,7 +739,7 @@ static void _http_queue_send_stream(struct http_server_t *server, bool stream_up
}
static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_server) {
struct http_server_t *server = (struct http_server_t *)v_server;
server_s *server = (server_s *)v_server;
bool stream_updated = false;
bool frame_updated = false;
@@ -773,7 +773,7 @@ static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_serv
}
}
static bool _expose_new_frame(struct http_server_t *server) {
static bool _expose_new_frame(server_s *server) {
bool updated = false;
A_MUTEX_LOCK(&STREAM(video->mutex));

View File

@@ -72,29 +72,29 @@
#include "static.h"
struct stream_client_t {
struct http_server_t *server;
struct evhttp_request *request;
typedef struct stream_client_sx {
struct server_sx *server;
struct evhttp_request *request;
char *key;
bool extra_headers;
bool advance_headers;
bool dual_final_frames;
char *key;
bool extra_headers;
bool advance_headers;
bool dual_final_frames;
char id[37]; // ex. "1b4e28ba-2fa1-11d2-883f-0016d3cca427" + "\0"
bool need_initial;
bool need_first_frame;
bool updated_prev;
unsigned fps;
unsigned fps_accum;
long long fps_accum_second;
char id[37]; // ex. "1b4e28ba-2fa1-11d2-883f-0016d3cca427" + "\0"
bool need_initial;
bool need_first_frame;
bool updated_prev;
unsigned fps;
unsigned fps_accum;
long long fps_accum_second;
struct stream_client_t *prev;
struct stream_client_t *next;
};
struct stream_client_sx *prev;
struct stream_client_sx *next;
} stream_client_s;
struct exposed_t {
struct frame_t *frame;
typedef struct {
frame_s *frame;
unsigned captured_fps;
unsigned queued_fps;
bool online;
@@ -106,21 +106,21 @@ struct exposed_t {
bool notify_last_online;
unsigned notify_last_width;
unsigned notify_last_height;
};
} exposed_s;
struct http_server_runtime_t {
struct event_base *base;
struct evhttp *http;
evutil_socket_t unix_fd;
char *auth_token;
struct event *refresh;
struct stream_t *stream;
struct exposed_t *exposed;
struct stream_client_t *stream_clients;
unsigned stream_clients_count;
};
typedef struct {
struct event_base *base;
struct evhttp *http;
evutil_socket_t unix_fd;
char *auth_token;
struct event *refresh;
stream_s *stream;
exposed_s *exposed;
stream_client_s *stream_clients;
unsigned stream_clients_count;
} server_runtime_s;
struct http_server_t {
typedef struct server_sx {
char *host;
unsigned port;
char *unix_path;
@@ -141,13 +141,13 @@ struct http_server_t {
bool notify_parent;
struct http_server_runtime_t *run;
};
server_runtime_s *run;
} server_s;
struct http_server_t *http_server_init(struct stream_t *stream);
void http_server_destroy(struct http_server_t *server);
server_s *server_init(stream_s *stream);
void server_destroy(server_s *server);
int http_server_listen(struct http_server_t *server);
void http_server_loop(struct http_server_t *server);
void http_server_loop_break(struct http_server_t *server);
int server_listen(server_s *server);
void server_loop(server_s *server);
void server_loop_break(server_s *server);

View File

@@ -50,12 +50,12 @@
#endif
struct _main_context_t {
struct stream_t *stream;
struct http_server_t *server;
};
typedef struct {
stream_s *stream;
server_s *server;
} _main_context_s;
static struct _main_context_t *_ctx;
static _main_context_s *_ctx;
static void _block_thread_signals(void) {
sigset_t mask;
@@ -75,14 +75,14 @@ static void *_stream_loop_thread(UNUSED void *arg) {
static void *_server_loop_thread(UNUSED void *arg) {
A_THREAD_RENAME("http");
_block_thread_signals();
http_server_loop(_ctx->server);
server_loop(_ctx->server);
return NULL;
}
static void _signal_handler(int signum) {
LOG_INFO_NOLOCK("===== Stopping by %s =====", (signum == SIGTERM ? "SIGTERM" : "SIGINT"));
stream_loop_break(_ctx->stream);
http_server_loop_break(_ctx->server);
server_loop_break(_ctx->server);
}
static void _install_signal_handlers(void) {
@@ -105,11 +105,11 @@ static void _install_signal_handlers(void) {
}
int main(int argc, char *argv[]) {
struct options_t *options;
struct device_t *dev;
struct encoder_t *encoder;
struct stream_t *stream;
struct http_server_t *server;
options_s *options;
device_s *dev;
encoder_s *encoder;
stream_s *stream;
server_s *server;
int exit_code = 0;
LOGGING_INIT;
@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) {
dev = device_init();
encoder = encoder_init();
stream = stream_init(dev, encoder);
server = http_server_init(stream);
server = server_init(stream);
if ((exit_code = options_parse(options, dev, encoder, stream, server)) == 0) {
# ifdef WITH_GPIO
@@ -130,13 +130,13 @@ int main(int argc, char *argv[]) {
pthread_t stream_loop_tid;
pthread_t server_loop_tid;
struct _main_context_t ctx;
_main_context_s ctx;
ctx.stream = stream;
ctx.server = server;
_ctx = &ctx;
if ((exit_code = http_server_listen(server)) == 0) {
if ((exit_code = server_listen(server)) == 0) {
# ifdef WITH_GPIO
gpio_set_prog_running(true);
# endif
@@ -153,7 +153,7 @@ int main(int argc, char *argv[]) {
# endif
}
http_server_destroy(server);
server_destroy(server);
stream_destroy(stream);
encoder_destroy(encoder);
device_destroy(dev);

View File

@@ -205,18 +205,15 @@ static const struct option _LONG_OPTS[] = {
static int _parse_resolution(const char *str, unsigned *width, unsigned *height, bool limited);
#ifdef WITH_OMX
static int _parse_glitched_resolutions(const char *str, struct encoder_t *encoder);
static int _parse_glitched_resolutions(const char *str, encoder_s *encoder);
#endif
static void _features(void);
static void _help(
struct device_t *dev, struct encoder_t *encoder,
struct stream_t *stream, struct http_server_t *server);
static void _help(device_s *dev, encoder_s *encoder, stream_s *stream, server_s *server);
struct options_t *options_init(int argc, char *argv[]) {
struct options_t *options;
options_s *options_init(int argc, char *argv[]) {
options_s *options;
A_CALLOC(options, 1);
options->argc = argc;
@@ -230,7 +227,7 @@ struct options_t *options_init(int argc, char *argv[]) {
return options;
}
void options_destroy(struct options_t *options) {
void options_destroy(options_s *options) {
if (options->blank) {
frame_destroy(options->blank);
}
@@ -242,10 +239,7 @@ void options_destroy(struct options_t *options) {
}
int options_parse(
struct options_t *options, struct device_t *dev, struct encoder_t *encoder,
struct stream_t *stream, struct http_server_t *server) {
int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_s *stream, server_s *server) {
# define OPT_SET(_dest, _value) { \
_dest = _value; \
break; \
@@ -487,7 +481,7 @@ static int _parse_resolution(const char *str, unsigned *width, unsigned *height,
}
#ifdef WITH_OMX
static int _parse_glitched_resolutions(const char *str, struct encoder_t *encoder) {
static int _parse_glitched_resolutions(const char *str, encoder_s *encoder) {
char *str_copy;
char *ptr;
unsigned count = 0;
@@ -574,10 +568,7 @@ static void _features(void) {
# endif
}
static void _help(
struct device_t *dev, struct encoder_t *encoder,
struct stream_t *stream, struct http_server_t *server) {
static void _help(device_s *dev, encoder_s *encoder, stream_s *stream, server_s *server) {
printf("\nuStreamer - Lightweight and fast MJPG-HTTP streamer\n");
printf("═══════════════════════════════════════════════════\n\n");
printf("Version: %s; license: GPLv3\n", VERSION);

View File

@@ -48,17 +48,15 @@
#endif
struct options_t {
int argc;
char **argv;
char **argv_copy;
struct frame_t *blank;
};
typedef struct {
int argc;
char **argv;
char **argv_copy;
frame_s *blank;
} options_s;
struct options_t *options_init(int argc, char *argv[]);
void options_destroy(struct options_t *options);
options_s *options_init(int argc, char *argv[]);
void options_destroy(options_s *options);
int options_parse(
struct options_t *options, struct device_t *dev, struct encoder_t *encoder,
struct stream_t *stream, struct http_server_t *server);
int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_s *stream, server_s *server);

View File

@@ -23,70 +23,70 @@
#include "stream.h"
struct _worker_t {
pthread_t tid;
unsigned number;
atomic_bool *proc_stop;
atomic_bool *workers_stop;
typedef struct _worker_sx {
pthread_t tid;
unsigned number;
atomic_bool *proc_stop;
atomic_bool *workers_stop;
long double last_comp_time;
char *frame_role;
struct frame_t *frame;
long double last_comp_time;
char *frame_role;
frame_s *frame;
pthread_mutex_t has_job_mutex;
unsigned buf_index;
atomic_bool has_job;
bool job_timely;
bool job_failed;
long double job_start_ts;
pthread_cond_t has_job_cond;
pthread_mutex_t has_job_mutex;
unsigned buf_index;
atomic_bool has_job;
bool job_timely;
bool job_failed;
long double job_start_ts;
pthread_cond_t has_job_cond;
pthread_mutex_t *free_workers_mutex;
unsigned *free_workers;
pthread_cond_t *free_workers_cond;
pthread_mutex_t *free_workers_mutex;
unsigned *free_workers;
pthread_cond_t *free_workers_cond;
struct _worker_t *order_prev;
struct _worker_t *order_next;
struct _worker_sx *order_prev;
struct _worker_sx *order_next;
struct stream_t *stream;
};
stream_s *stream;
} _worker_s;
struct _workers_pool_t {
unsigned n_workers;
struct _worker_t *workers;
struct _worker_t *oldest_wr;
struct _worker_t *latest_wr;
typedef struct {
unsigned n_workers;
_worker_s *workers;
_worker_s *oldest_wr;
_worker_s *latest_wr;
long double approx_comp_time;
long double approx_comp_time;
pthread_mutex_t free_workers_mutex;
unsigned free_workers;
pthread_cond_t free_workers_cond;
pthread_mutex_t free_workers_mutex;
unsigned free_workers;
pthread_cond_t free_workers_cond;
atomic_bool workers_stop;
atomic_bool workers_stop;
long double desired_frames_interval;
};
long double desired_frames_interval;
} _pool_s;
static struct _workers_pool_t *_stream_init_loop(struct stream_t *stream);
static struct _workers_pool_t *_stream_init_one(struct stream_t *stream);
static void _stream_expose_frame(struct stream_t *stream, struct frame_t *frame, unsigned captured_fps);
static _pool_s *_stream_init_loop(stream_s *stream);
static _pool_s *_stream_init_one(stream_s *stream);
static void _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps);
static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream);
static void _workers_pool_destroy(struct _workers_pool_t *pool);
static _pool_s *_workers_pool_init(stream_s *stream);
static void _workers_pool_destroy(_pool_s *pool);
static void *_worker_thread(void *v_worker);
static struct _worker_t *_workers_pool_wait(struct _workers_pool_t *pool);
static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t *ready_wr, unsigned buf_index);
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool, struct _worker_t *ready_wr);
static _worker_s *_workers_pool_wait(_pool_s *pool);
static void _workers_pool_assign(_pool_s *pool, _worker_s *ready_wr, unsigned buf_index);
static long double _workers_pool_get_fluency_delay(_pool_s *pool, _worker_s *ready_wr);
struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
struct process_t *proc;
struct video_t *video;
struct stream_t *stream;
stream_s *stream_init(device_s *dev, encoder_s *encoder) {
process_s *proc;
video_s *video;
stream_s *stream;
A_CALLOC(proc, 1);
atomic_init(&proc->stop, false);
@@ -111,7 +111,7 @@ struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
return stream;
}
void stream_destroy(struct stream_t *stream) {
void stream_destroy(stream_s *stream) {
A_MUTEX_DESTROY(&stream->video->mutex);
frame_destroy(stream->video->frame);
free(stream->video);
@@ -119,15 +119,15 @@ void stream_destroy(struct stream_t *stream) {
free(stream);
}
void stream_loop(struct stream_t *stream) {
void stream_loop(stream_s *stream) {
# define DEV(_next) stream->dev->_next
struct _workers_pool_t *pool;
_pool_s *pool;
LOG_INFO("Using V4L2 device: %s", DEV(path));
LOG_INFO("Using desired FPS: %u", DEV(desired_fps));
# ifdef WITH_RAWSINK
struct rawsink_t *rawsink = NULL;
rawsink_s *rawsink = NULL;
if (stream->rawsink_name[0] != '\0') {
rawsink = rawsink_init(stream->rawsink_name, stream->rawsink_mode, stream->rawsink_rm, true);
}
@@ -143,7 +143,7 @@ void stream_loop(struct stream_t *stream) {
LOG_INFO("Capturing ...");
while (!atomic_load(&stream->proc->stop)) {
struct _worker_t *ready_wr;
_worker_s *ready_wr;
SEP_DEBUG('-');
LOG_DEBUG("Waiting for worker ...");
@@ -272,16 +272,16 @@ void stream_loop(struct stream_t *stream) {
# undef DEV
}
void stream_loop_break(struct stream_t *stream) {
void stream_loop_break(stream_s *stream) {
atomic_store(&stream->proc->stop, true);
}
void stream_switch_slowdown(struct stream_t *stream, bool slowdown) {
void stream_switch_slowdown(stream_s *stream, bool slowdown) {
atomic_store(&stream->proc->slowdown, slowdown);
}
static struct _workers_pool_t *_stream_init_loop(struct stream_t *stream) {
struct _workers_pool_t *pool = NULL;
static _pool_s *_stream_init_loop(stream_s *stream) {
_pool_s *pool = NULL;
int access_error = 0;
LOG_DEBUG("%s: stream->proc->stop=%d", __FUNCTION__, atomic_load(&stream->proc->stop));
@@ -313,7 +313,7 @@ static struct _workers_pool_t *_stream_init_loop(struct stream_t *stream) {
return pool;
}
static struct _workers_pool_t *_stream_init_one(struct stream_t *stream) {
static _pool_s *_stream_init_one(stream_s *stream) {
if (device_open(stream->dev) < 0) {
goto error;
}
@@ -329,10 +329,10 @@ static struct _workers_pool_t *_stream_init_one(struct stream_t *stream) {
return NULL;
}
static void _stream_expose_frame(struct stream_t *stream, struct frame_t *frame, unsigned captured_fps) {
static void _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps) {
# define VID(_next) stream->video->_next
struct frame_t *new = NULL;
frame_s *new = NULL;
A_MUTEX_LOCK(&VID(mutex));
@@ -382,11 +382,11 @@ static void _stream_expose_frame(struct stream_t *stream, struct frame_t *frame,
# undef VID
}
static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream) {
static _pool_s *_workers_pool_init(stream_s *stream) {
# define DEV(_next) stream->dev->_next
# define RUN(_next) stream->dev->run->_next
struct _workers_pool_t *pool;
_pool_s *pool;
LOG_INFO("Creating pool with %u workers ...", stream->encoder->run->n_workers);
@@ -437,7 +437,7 @@ static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream) {
return pool;
}
static void _workers_pool_destroy(struct _workers_pool_t *pool) {
static void _workers_pool_destroy(_pool_s *pool) {
LOG_INFO("Destroying workers pool ...");
atomic_store(&pool->workers_stop, true);
@@ -467,7 +467,7 @@ static void _workers_pool_destroy(struct _workers_pool_t *pool) {
}
static void *_worker_thread(void *v_worker) {
struct _worker_t *wr = (struct _worker_t *)v_worker;
_worker_s *wr = (_worker_s *)v_worker;
A_THREAD_RENAME("worker-%u", wr->number);
LOG_DEBUG("Hello! I am a worker #%u ^_^", wr->number);
@@ -520,8 +520,8 @@ static void *_worker_thread(void *v_worker) {
return NULL;
}
static struct _worker_t *_workers_pool_wait(struct _workers_pool_t *pool) {
struct _worker_t *ready_wr = NULL;
static _worker_s *_workers_pool_wait(_pool_s *pool) {
_worker_s *ready_wr = NULL;
A_MUTEX_LOCK(&pool->free_workers_mutex);
A_COND_WAIT_TRUE(pool->free_workers, &pool->free_workers_cond, &pool->free_workers_mutex);
@@ -549,7 +549,7 @@ static struct _worker_t *_workers_pool_wait(struct _workers_pool_t *pool) {
return ready_wr;
}
static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t *ready_wr, unsigned buf_index) {
static void _workers_pool_assign(_pool_s *pool, _worker_s *ready_wr, unsigned buf_index) {
if (pool->oldest_wr == NULL) {
pool->oldest_wr = ready_wr;
pool->latest_wr = pool->oldest_wr;
@@ -579,7 +579,7 @@ static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t
LOG_DEBUG("Assigned new frame in buffer %u to worker %u", buf_index, ready_wr->number);
}
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool, struct _worker_t *ready_wr) {
static long double _workers_pool_get_fluency_delay(_pool_s *pool, _worker_s *ready_wr) {
long double approx_comp_time;
long double min_delay;

View File

@@ -48,21 +48,21 @@
#endif
struct process_t {
typedef struct {
atomic_bool stop;
atomic_bool slowdown;
};
} process_s;
struct video_t {
struct frame_t *frame;
bool online;
unsigned captured_fps;
atomic_bool updated;
long double last_as_blank_ts;
pthread_mutex_t mutex;
};
typedef struct {
frame_s *frame;
bool online;
unsigned captured_fps;
atomic_bool updated;
long double last_as_blank_ts;
pthread_mutex_t mutex;
} video_s;
struct stream_t {
typedef struct {
int last_as_blank;
unsigned error_delay;
# ifdef WITH_RAWSINK
@@ -71,18 +71,18 @@ struct stream_t {
bool rawsink_rm;
# endif
struct device_t *dev;
struct encoder_t *encoder;
struct frame_t *blank;
device_s *dev;
encoder_s *encoder;
frame_s *blank;
struct process_t *proc;
struct video_t *video;
};
process_s *proc;
video_s *video;
} stream_s;
struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder);
void stream_destroy(struct stream_t *stream);
stream_s *stream_init(device_s *dev, encoder_s *encoder);
void stream_destroy(stream_s *stream);
void stream_loop(struct stream_t *stream);
void stream_loop_break(struct stream_t *stream);
void stream_switch_slowdown(struct stream_t *stream, bool slowdown);
void stream_loop(stream_s *stream);
void stream_loop_break(stream_s *stream);
void stream_switch_slowdown(stream_s *stream, bool slowdown);