some common macroses

This commit is contained in:
Devaev Maxim
2021-03-30 02:18:40 +03:00
parent 01bc0529e7
commit 04d1d3d5a6
12 changed files with 72 additions and 143 deletions

1
python/frame.c Symbolic link
View File

@@ -0,0 +1 @@
../src/libs/frame.c

1
python/frame.h Symbolic link
View File

@@ -0,0 +1 @@
../src/libs/frame.h

1
python/memsinksh.h Symbolic link
View File

@@ -0,0 +1 @@
../src/libs/memsinksh.h

View File

@@ -1,3 +1,5 @@
import os
from distutils.core import Extension from distutils.core import Extension
from distutils.core import setup from distutils.core import setup
@@ -16,11 +18,8 @@ if __name__ == "__main__":
"ustreamer", "ustreamer",
libraries=["rt", "m", "pthread"], libraries=["rt", "m", "pthread"],
undef_macros=["NDEBUG"], undef_macros=["NDEBUG"],
sources=["ustreamer.c"], sources=[name for name in os.listdir(".") if name.endswith(".c")],
depends=[ depends=[name for name in os.listdir(".") if name.endswith(".h")],
"../src/libs/tools.h",
"../src/libs/memsinksh.h",
],
), ),
], ],
) )

1
python/tools.h Symbolic link
View File

@@ -0,0 +1 @@
../src/libs/tools.h

View File

@@ -13,31 +13,11 @@
#include <Python.h> #include <Python.h>
#include "../src/libs/tools.h" // Just a header without C-sources #include "tools.h"
#include "../src/libs/memsinksh.h" // No sources again #include "frame.h"
#include "memsinksh.h"
typedef struct {
uint64_t id;
long double ts;
uint8_t *data;
size_t used;
size_t allocated;
unsigned width;
unsigned height;
unsigned format;
unsigned stride;
bool online;
bool key;
long double grab_ts;
long double encode_begin_ts;
long double encode_end_ts;
} tmp_frame_s;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
@@ -49,12 +29,14 @@ typedef struct {
int fd; int fd;
memsink_shared_s *mem; memsink_shared_s *mem;
tmp_frame_s *tmp_frame; uint64_t frame_id;
long double frame_ts;
frame_s *frame;
} MemsinkObject; } MemsinkObject;
#define MEM(_next) self->mem->_next #define MEM(_next) self->mem->_next
#define TMP(_next) self->tmp_frame->_next #define FRAME(_next) self->frame->_next
static void MemsinkObject_destroy_internals(MemsinkObject *self) { static void MemsinkObject_destroy_internals(MemsinkObject *self) {
@@ -66,12 +48,9 @@ static void MemsinkObject_destroy_internals(MemsinkObject *self) {
close(self->fd); close(self->fd);
self->fd = -1; self->fd = -1;
} }
if (self->tmp_frame) { if (self->frame) {
if (TMP(data)) { frame_destroy(self->frame);
free(TMP(data)); self->frame = NULL;
}
free(self->tmp_frame);
self->tmp_frame = NULL;
} }
} }
@@ -99,9 +78,7 @@ static int MemsinkObject_init(MemsinkObject *self, PyObject *args, PyObject *kwa
# undef SET_DOUBLE # undef SET_DOUBLE
A_CALLOC(self->tmp_frame, 1); self->frame = frame_init("memsink_client");
TMP(allocated) = 512 * 1024;
A_REALLOC(TMP(data), TMP(allocated));
if ((self->fd = shm_open(self->obj, O_RDWR, 0)) == -1) { if ((self->fd = shm_open(self->obj, O_RDWR, 0)) == -1) {
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
@@ -177,24 +154,16 @@ static int wait_frame(MemsinkObject *self) {
RETURN_OS_ERROR; RETURN_OS_ERROR;
} else if (retval == 0) { } else if (retval == 0) {
if (MEM(magic) == MEMSINK_MAGIC && MEM(version) == MEMSINK_VERSION && TMP(id) != MEM(id)) { if (MEM(magic) == MEMSINK_MAGIC && MEM(version) == MEMSINK_VERSION && MEM(id) != self->frame_id) {
if (self->drop_same_frames > 0) { if (self->drop_same_frames > 0) {
# define CMP(_field) (TMP(_field) == MEM(_field))
if ( if (
CMP(used) FRAME_COMPARE_META_USED_NOTS(self->mem, self->frame)
&& CMP(width) && (self->frame_ts + self->drop_same_frames > now)
&& CMP(height) && !memcmp(FRAME(data), MEM(data), MEM(used))
&& CMP(format)
&& CMP(stride)
&& CMP(online)
&& CMP(key)
&& (TMP(ts) + self->drop_same_frames > now)
&& !memcmp(TMP(data), MEM(data), MEM(used))
) { ) {
TMP(id) = MEM(id); self->frame_id = MEM(id);
goto drop; goto drop;
} }
# undef CMP
} }
Py_BLOCK_THREADS Py_BLOCK_THREADS
@@ -236,30 +205,11 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS
default: return NULL; default: return NULL;
} }
# define COPY(_field) TMP(_field) = MEM(_field) frame_set_data(self->frame, MEM(data), MEM(used));
COPY(width); FRAME_COPY_META(self->mem, self->frame);
COPY(height); self->frame_id = MEM(id);
COPY(format); self->frame_ts = get_now_monotonic();
COPY(stride); MEM(last_client_ts) = self->frame_ts;
COPY(online);
COPY(key);
COPY(grab_ts);
COPY(encode_begin_ts);
COPY(encode_end_ts);
COPY(used);
# undef COPY
if (TMP(allocated) < MEM(used)) {
size_t size = MEM(used) + (512 * 1024);
A_REALLOC(TMP(data), size);
TMP(allocated) = size;
}
memcpy(TMP(data), MEM(data), MEM(used));
TMP(used) = MEM(used);
TMP(id) = MEM(id);
TMP(ts) = get_now_monotonic();
MEM(last_client_ts) = TMP(ts);
if (flock(self->fd, LOCK_UN) < 0) { if (flock(self->fd, LOCK_UN) < 0) {
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
@@ -281,7 +231,7 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS
} \ } \
Py_DECREF(_tmp); \ Py_DECREF(_tmp); \
} }
# define SET_NUMBER(_key, _from, _to) SET_VALUE(#_key, Py##_to##_From##_from(TMP(_key))) # define SET_NUMBER(_key, _from, _to) SET_VALUE(#_key, Py##_to##_From##_from(FRAME(_key)))
SET_NUMBER(width, Long, Long); SET_NUMBER(width, Long, Long);
SET_NUMBER(height, Long, Long); SET_NUMBER(height, Long, Long);
@@ -292,7 +242,7 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS
SET_NUMBER(grab_ts, Double, Float); SET_NUMBER(grab_ts, Double, Float);
SET_NUMBER(encode_begin_ts, Double, Float); SET_NUMBER(encode_begin_ts, Double, Float);
SET_NUMBER(encode_end_ts, Double, Float); SET_NUMBER(encode_end_ts, Double, Float);
SET_VALUE("data", PyBytes_FromStringAndSize((const char *)TMP(data), TMP(used))); SET_VALUE("data", PyBytes_FromStringAndSize((const char *)FRAME(data), FRAME(used)));
# undef SET_NUMBER # undef SET_NUMBER
# undef SET_VALUE # undef SET_VALUE
@@ -376,5 +326,5 @@ PyMODINIT_FUNC PyInit_ustreamer(void) { // cppcheck-suppress unusedFunction
return module; return module;
} }
#undef TMP #undef FRAME
#undef MEM #undef MEM

View File

@@ -43,8 +43,8 @@ void frame_destroy(frame_s *frame) {
void frame_realloc_data(frame_s *frame, size_t size) { void frame_realloc_data(frame_s *frame, size_t size) {
assert(frame->managed); assert(frame->managed);
if (frame->allocated < size) { if (frame->allocated < size) {
LOG_DEBUG("Increasing frame buffer '%s': %zu -> %zu (+%zu)", //LOG_DEBUG("Increasing frame buffer '%s': %zu -> %zu (+%zu)",
frame->name, frame->allocated, size, size - frame->allocated); // frame->name, frame->allocated, size, size - frame->allocated);
A_REALLOC(frame->data, size); A_REALLOC(frame->data, size);
frame->allocated = size; frame->allocated = size;
} }
@@ -65,44 +65,18 @@ void frame_append_data(frame_s *frame, const uint8_t *data, size_t size) {
frame->used = new_used; frame->used = new_used;
} }
#define COPY(_field) dest->_field = src->_field
void frame_copy(const frame_s *src, frame_s *dest) { void frame_copy(const frame_s *src, frame_s *dest) {
assert(dest->managed); assert(dest->managed);
frame_set_data(dest, src->data, src->used); frame_set_data(dest, src->data, src->used);
COPY(used); FRAME_COPY_META(src, dest);
frame_copy_meta(src, dest);
} }
void frame_copy_meta(const frame_s *src, frame_s *dest) {
// Don't copy the name
COPY(width);
COPY(height);
COPY(format);
COPY(stride);
COPY(online);
COPY(key);
COPY(grab_ts);
COPY(encode_begin_ts);
COPY(encode_end_ts);
}
#undef COPY
bool frame_compare(const frame_s *a, const frame_s *b) { bool frame_compare(const frame_s *a, const frame_s *b) {
# define CMP(_field) (a->_field == b->_field)
return ( return (
a->allocated && b->allocated a->allocated && b->allocated
&& CMP(used) && FRAME_COMPARE_META_USED_NOTS(a, b)
&& CMP(width)
&& CMP(height)
&& CMP(format)
&& CMP(stride)
&& CMP(online)
&& CMP(key)
&& !memcmp(a->data, b->data, b->used) && !memcmp(a->data, b->data, b->used)
); );
# undef CMP
} }
unsigned frame_get_padding(const frame_s *frame) { unsigned frame_get_padding(const frame_s *frame) {

View File

@@ -32,7 +32,7 @@
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include "tools.h" #include "tools.h"
#include "logging.h" //#include "logging.h"
typedef struct { typedef struct {
@@ -61,6 +61,29 @@ typedef struct {
} frame_s; } frame_s;
#define FRAME_COPY_META(_src, _dest) { \
_dest->width = _src->width; \
_dest->height = _src->height; \
_dest->format = _src->format; \
_dest->stride = _src->stride; \
_dest->online = _src->online; \
_dest->key = _src->key; \
_dest->grab_ts = _src->grab_ts; \
_dest->encode_begin_ts = _src->encode_begin_ts; \
_dest->encode_end_ts = _src->encode_end_ts; \
}
#define FRAME_COMPARE_META_USED_NOTS(_a, _b) ( \
_a->used == _b->used \
&& _a->width == _b->width \
&& _a->height == _b->height \
&& _a->format == _b->format \
&& _a->stride == _b->stride \
&& _a->online == _b->online \
&& _a->key == _b->key \
)
frame_s *frame_init(const char *name); frame_s *frame_init(const char *name);
void frame_destroy(frame_s *frame); void frame_destroy(frame_s *frame);
@@ -69,7 +92,6 @@ 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_append_data(frame_s *frame, const uint8_t *data, size_t size);
void frame_copy(const frame_s *src, frame_s *dest); void frame_copy(const frame_s *src, frame_s *dest);
void frame_copy_meta(const frame_s *src, frame_s *dest);
bool frame_compare(const frame_s *a, const frame_s *b); bool frame_compare(const frame_s *a, const frame_s *b);
unsigned frame_get_padding(const frame_s *frame); unsigned frame_get_padding(const frame_s *frame);

View File

@@ -93,7 +93,7 @@ void memsink_destroy(memsink_s *sink) {
} }
bool memsink_server_check(memsink_s *sink, const frame_s *frame) { bool memsink_server_check(memsink_s *sink, const frame_s *frame) {
// Возвращает true, если если клиенты ИЛИ изменились метаданные // Возвращает true, если есть клиенты ИЛИ изменились метаданные
assert(sink->server); assert(sink->server);
@@ -108,9 +108,7 @@ bool memsink_server_check(memsink_s *sink, const frame_s *frame) {
sink->has_clients = (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic()); sink->has_clients = (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic());
# define NEQ(_field) (sink->mem->_field != frame->_field) bool retval = (sink->has_clients || !FRAME_COMPARE_META_USED_NOTS(sink->mem, frame));
bool retval = (sink->has_clients || NEQ(width) || NEQ(height) || NEQ(format) || NEQ(stride) || NEQ(online) || NEQ(key));
# undef NEQ
if (flock(sink->fd, LOCK_UN) < 0) { if (flock(sink->fd, LOCK_UN) < 0) {
LOG_PERROR("%s-sink: Can't unlock memory", sink->name); LOG_PERROR("%s-sink: Can't unlock memory", sink->name);
@@ -133,24 +131,16 @@ int memsink_server_put(memsink_s *sink, const frame_s *frame) {
if (flock_timedwait_monotonic(sink->fd, 1) == 0) { if (flock_timedwait_monotonic(sink->fd, 1) == 0) {
LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name); LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name);
# define COPY(_field) sink->mem->_field = frame->_field
sink->last_id = get_now_id(); sink->last_id = get_now_id();
sink->mem->id = sink->last_id; sink->mem->id = sink->last_id;
COPY(used);
COPY(width);
COPY(height);
COPY(format);
COPY(stride);
COPY(online);
COPY(key);
COPY(grab_ts);
COPY(encode_begin_ts);
COPY(encode_end_ts);
sink->has_clients = (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic());
memcpy(sink->mem->data, frame->data, frame->used); memcpy(sink->mem->data, frame->data, frame->used);
sink->mem->used = frame->used;
FRAME_COPY_META(frame, sink->mem);
sink->mem->magic = MEMSINK_MAGIC; sink->mem->magic = MEMSINK_MAGIC;
sink->mem->version = MEMSINK_VERSION; sink->mem->version = MEMSINK_VERSION;
# undef COPY sink->has_clients = (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic());
if (flock(sink->fd, LOCK_UN) < 0) { if (flock(sink->fd, LOCK_UN) < 0) {
LOG_PERROR("%s-sink: Can't unlock memory", sink->name); LOG_PERROR("%s-sink: Can't unlock memory", sink->name);
@@ -189,19 +179,9 @@ int memsink_client_get(memsink_s *sink, frame_s *frame) { // cppcheck-suppress u
goto done; goto done;
} }
if (sink->mem->id != sink->last_id) { // When updated if (sink->mem->id != sink->last_id) { // When updated
# define COPY(_field) frame->_field = sink->mem->_field
sink->last_id = sink->mem->id; sink->last_id = sink->mem->id;
COPY(width);
COPY(height);
COPY(format);
COPY(stride);
COPY(online);
COPY(key);
COPY(grab_ts);
COPY(encode_begin_ts);
COPY(encode_end_ts);
frame_set_data(frame, sink->mem->data, sink->mem->used); frame_set_data(frame, sink->mem->data, sink->mem->used);
# undef COPY FRAME_COPY_META(sink->mem, frame);
retval = 0; retval = 0;
} }
sink->mem->last_client_ts = get_now_monotonic(); sink->mem->last_client_ts = get_now_monotonic();

View File

@@ -57,7 +57,7 @@ int unjpeg(const frame_s *src, frame_s *dest, bool decode) {
jpeg_start_decompress(&jpeg); jpeg_start_decompress(&jpeg);
frame_copy_meta(src, dest); FRAME_COPY_META(src, dest);
dest->format = V4L2_PIX_FMT_RGB24; dest->format = V4L2_PIX_FMT_RGB24;
dest->width = jpeg.output_width; dest->width = jpeg.output_width;
dest->height = jpeg.output_height; dest->height = jpeg.output_height;

View File

@@ -244,7 +244,7 @@ static bool _worker_run_job(worker_s *wr) {
assert(ER(type) != ENCODER_TYPE_UNKNOWN); assert(ER(type) != ENCODER_TYPE_UNKNOWN);
assert(src->used > 0); assert(src->used > 0);
frame_copy_meta(src, dest); FRAME_COPY_META(src, dest);
dest->format = V4L2_PIX_FMT_JPEG; dest->format = V4L2_PIX_FMT_JPEG;
dest->stride = 0; dest->stride = 0;
dest->encode_begin_ts = get_now_monotonic(); dest->encode_begin_ts = get_now_monotonic();

View File

@@ -267,7 +267,7 @@ int h264_encoder_compress(h264_encoder_s *enc, const frame_s *src, int src_vcsm_
assert(enc->format == src->format); assert(enc->format == src->format);
assert(enc->stride == src->stride); assert(enc->stride == src->stride);
frame_copy_meta(src, dest); FRAME_COPY_META(src, dest);
dest->encode_begin_ts = get_now_monotonic(); dest->encode_begin_ts = get_now_monotonic();
dest->format = V4L2_PIX_FMT_H264; dest->format = V4L2_PIX_FMT_H264;
dest->stride = 0; dest->stride = 0;