mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-28 04:36:33 +00:00
refactoring, const
This commit is contained in:
@@ -168,11 +168,11 @@ int us_audio_get_encoded(us_audio_s *audio, uint8_t *data, size_t *size, uint64_
|
||||
static void *_pcm_thread(void *v_audio) {
|
||||
US_THREAD_RENAME("us_a_pcm");
|
||||
|
||||
us_audio_s *audio = (us_audio_s *)v_audio;
|
||||
us_audio_s *const audio = (us_audio_s *)v_audio;
|
||||
uint8_t in[_MAX_BUF8];
|
||||
|
||||
while (!atomic_load(&audio->stop)) {
|
||||
int frames = snd_pcm_readi(audio->pcm, in, audio->pcm_frames);
|
||||
const int frames = snd_pcm_readi(audio->pcm, in, audio->pcm_frames);
|
||||
if (frames < 0) {
|
||||
_JLOG_PERROR_ALSA(frames, "audio", "Fatal: Can't capture PCM frames");
|
||||
break;
|
||||
@@ -198,14 +198,14 @@ static void *_pcm_thread(void *v_audio) {
|
||||
static void *_encoder_thread(void *v_audio) {
|
||||
US_THREAD_RENAME("us_a_enc");
|
||||
|
||||
us_audio_s *audio = (us_audio_s *)v_audio;
|
||||
us_audio_s *const audio = (us_audio_s *)v_audio;
|
||||
int16_t in_res[_MAX_BUF16];
|
||||
|
||||
while (!atomic_load(&audio->stop)) {
|
||||
_pcm_buffer_s *in;
|
||||
if (!us_queue_get(audio->pcm_queue, (void **)&in, 0.1)) {
|
||||
int16_t *in_ptr;
|
||||
if (audio->res) {
|
||||
if (audio->res != NULL) {
|
||||
assert(audio->pcm_hz != _ENCODER_INPUT_HZ);
|
||||
uint32_t in_count = audio->pcm_frames;
|
||||
uint32_t out_count = _HZ_TO_FRAMES(_ENCODER_INPUT_HZ);
|
||||
@@ -218,7 +218,7 @@ static void *_encoder_thread(void *v_audio) {
|
||||
|
||||
_enc_buffer_s *out;
|
||||
US_CALLOC(out, 1);
|
||||
int size = opus_encode(audio->enc, in_ptr, _HZ_TO_FRAMES(_ENCODER_INPUT_HZ), out->data, US_ARRAY_LEN(out->data));
|
||||
const int size = opus_encode(audio->enc, in_ptr, _HZ_TO_FRAMES(_ENCODER_INPUT_HZ), out->data, US_ARRAY_LEN(out->data));
|
||||
free(in);
|
||||
if (size < 0) {
|
||||
_JLOG_PERROR_OPUS(size, "audio", "Fatal: Can't encode PCM frame to OPUS");
|
||||
|
||||
@@ -70,7 +70,7 @@ void us_janus_client_send(us_janus_client_s *client, const us_rtp_s *rtp) {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
us_rtp_s *new = us_rtp_dup(rtp);
|
||||
us_rtp_s *const new = us_rtp_dup(rtp);
|
||||
if (us_queue_put((new->video ? client->video_queue : client->audio_queue), new, 0) != 0) {
|
||||
US_JLOG_ERROR("client", "Session %p %s queue is full",
|
||||
client->session, (new->video ? "video" : "audio"));
|
||||
@@ -87,8 +87,8 @@ static void *_audio_thread(void *v_client) {
|
||||
}
|
||||
|
||||
static void *_common_thread(void *v_client, bool video) {
|
||||
us_janus_client_s *client = (us_janus_client_s *)v_client;
|
||||
us_queue_s *queue = (video ? client->video_queue : client->audio_queue);
|
||||
us_janus_client_s *const client = (us_janus_client_s *)v_client;
|
||||
us_queue_s *const queue = (video ? client->video_queue : client->audio_queue);
|
||||
assert(queue != NULL); // Audio may be NULL
|
||||
|
||||
while (!atomic_load(&client->stop)) {
|
||||
|
||||
@@ -67,9 +67,7 @@ us_config_s *us_config_init(const char *config_dir_path) {
|
||||
us_config_destroy(config);
|
||||
config = NULL;
|
||||
ok:
|
||||
if (jcfg) {
|
||||
janus_config_destroy(jcfg);
|
||||
}
|
||||
US_DELETE(jcfg, janus_config_destroy);
|
||||
free(config_file_path);
|
||||
return config;
|
||||
}
|
||||
@@ -87,11 +85,11 @@ static char *_get_value(janus_config *jcfg, const char *section, const char *opt
|
||||
if (option_obj == NULL || option_obj->value == NULL || option_obj->value[0] == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
return strdup(option_obj->value);
|
||||
return us_strdup(option_obj->value);
|
||||
}
|
||||
|
||||
static bool _get_bool(janus_config *jcfg, const char *section, const char *option, bool def) {
|
||||
char *tmp = _get_value(jcfg, section, option);
|
||||
char *const tmp = _get_value(jcfg, section, option);
|
||||
bool value = def;
|
||||
if (tmp != NULL) {
|
||||
value = (!strcasecmp(tmp, "1") || !strcasecmp(tmp, "true") || !strcasecmp(tmp, "yes"));
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
|
||||
int us_memsink_fd_wait_frame(int fd, us_memsink_shared_s* mem, uint64_t last_id) {
|
||||
long double deadline_ts = us_get_now_monotonic() + 1; // wait_timeout
|
||||
const long double deadline_ts = us_get_now_monotonic() + 1; // wait_timeout
|
||||
long double now;
|
||||
do {
|
||||
int result = us_flock_timedwait_monotonic(fd, 1); // lock_timeout
|
||||
const int result = us_flock_timedwait_monotonic(fd, 1); // lock_timeout
|
||||
now = us_get_now_monotonic();
|
||||
if (result < 0 && errno != EWOULDBLOCK) {
|
||||
US_JLOG_PERROR("video", "Can't lock memsink");
|
||||
|
||||
@@ -96,7 +96,7 @@ janus_plugin *create(void);
|
||||
|
||||
|
||||
#define _IF_NOT_REPORTED(...) { \
|
||||
unsigned _error_code = __LINE__; \
|
||||
const unsigned _error_code = __LINE__; \
|
||||
if (error_reported != _error_code) { __VA_ARGS__; error_reported = _error_code; } \
|
||||
}
|
||||
|
||||
@@ -147,9 +147,9 @@ static void *_video_sink_thread(UNUSED void *arg) {
|
||||
|
||||
US_JLOG_INFO("video", "Memsink opened; reading frames ...");
|
||||
while (!_STOP && _HAS_WATCHERS) {
|
||||
int result = us_memsink_fd_wait_frame(fd, mem, frame_id);
|
||||
const int result = us_memsink_fd_wait_frame(fd, mem, frame_id);
|
||||
if (result == 0) {
|
||||
us_frame_s *frame = us_memsink_fd_get_frame(fd, mem, &frame_id);
|
||||
us_frame_s *const frame = us_memsink_fd_get_frame(fd, mem, &frame_id);
|
||||
if (frame == NULL) {
|
||||
goto close_memsink;
|
||||
}
|
||||
@@ -180,8 +180,8 @@ static void *_video_sink_thread(UNUSED void *arg) {
|
||||
static void *_audio_thread(UNUSED void *arg) {
|
||||
US_THREAD_RENAME("us_audio");
|
||||
atomic_store(&_g_audio_tid_created, true);
|
||||
assert(_g_config->audio_dev_name);
|
||||
assert(_g_config->tc358743_dev_path);
|
||||
assert(_g_config->audio_dev_name != NULL);
|
||||
assert(_g_config->tc358743_dev_path != NULL);
|
||||
|
||||
unsigned error_reported = 0;
|
||||
|
||||
@@ -220,7 +220,7 @@ static void *_audio_thread(UNUSED void *arg) {
|
||||
size_t size = US_RTP_DATAGRAM_SIZE - US_RTP_HEADER_SIZE;
|
||||
uint8_t data[size];
|
||||
uint64_t pts;
|
||||
int result = us_audio_get_encoded(audio, data, &size, &pts);
|
||||
const int result = us_audio_get_encoded(audio, data, &size, &pts);
|
||||
if (result == 0) {
|
||||
_LOCK_AUDIO;
|
||||
us_rtpa_wrap(_g_rtpa, data, size, pts);
|
||||
@@ -260,7 +260,7 @@ static int _plugin_init(janus_callbacks *gw, const char *config_dir_path) {
|
||||
|
||||
_g_video_queue = us_queue_init(1024);
|
||||
_g_rtpv = us_rtpv_init(_relay_rtp_clients, _g_config->video_zero_playout_delay);
|
||||
if (_g_config->audio_dev_name) {
|
||||
if (_g_config->audio_dev_name != NULL) {
|
||||
_g_rtpa = us_rtpa_init(_relay_rtp_clients);
|
||||
US_THREAD_CREATE(&_g_audio_tid, _audio_thread, NULL);
|
||||
}
|
||||
@@ -299,7 +299,7 @@ static void _plugin_create_session(janus_plugin_session *session, int *err) {
|
||||
_IF_DISABLED({ *err = -1; return; });
|
||||
_LOCK_ALL;
|
||||
US_JLOG_INFO("main", "Creating session %p ...", session);
|
||||
us_janus_client_s *client = us_janus_client_init(_g_gw, session, (_g_config->audio_dev_name != NULL));
|
||||
us_janus_client_s *const client = us_janus_client_init(_g_gw, session, (_g_config->audio_dev_name != NULL));
|
||||
US_LIST_APPEND(_g_clients, client);
|
||||
atomic_store(&_g_has_watchers, true);
|
||||
_UNLOCK_ALL;
|
||||
@@ -373,8 +373,8 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
assert(transaction != NULL);
|
||||
|
||||
# define FREE_MSG_JSEP { \
|
||||
if (msg) json_decref(msg); \
|
||||
if (jsep) json_decref(jsep); \
|
||||
US_DELETE(msg, json_decref); \
|
||||
US_DELETE(jsep, json_decref); \
|
||||
}
|
||||
|
||||
if (session == NULL || msg == NULL) {
|
||||
@@ -393,23 +393,23 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
json_decref(m_event); \
|
||||
}
|
||||
|
||||
json_t *request_obj = json_object_get(msg, "request");
|
||||
json_t *const request_obj = json_object_get(msg, "request");
|
||||
if (request_obj == NULL) {
|
||||
PUSH_ERROR(400, "Request missing");
|
||||
goto ok_wait;
|
||||
}
|
||||
|
||||
const char *request_str = json_string_value(request_obj);
|
||||
if (!request_str) {
|
||||
const char *const request_str = json_string_value(request_obj);
|
||||
if (request_str == NULL) {
|
||||
PUSH_ERROR(400, "Request not a string");
|
||||
goto ok_wait;
|
||||
}
|
||||
// US_JLOG_INFO("main", "Message: %s", request_str);
|
||||
|
||||
# define PUSH_STATUS(x_status, x_jsep) { \
|
||||
json_t *m_event = json_object(); \
|
||||
json_t *const m_event = json_object(); \
|
||||
json_object_set_new(m_event, "ustreamer", json_string("event")); \
|
||||
json_t *m_result = json_object(); \
|
||||
json_t *const m_result = json_object(); \
|
||||
json_object_set_new(m_result, "status", json_string(x_status)); \
|
||||
json_object_set_new(m_event, "result", m_result); \
|
||||
_g_gw->push_event(session, create(), transaction, m_event, x_jsep); \
|
||||
@@ -425,12 +425,12 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
} else if (!strcmp(request_str, "watch")) {
|
||||
char *sdp;
|
||||
{
|
||||
char *video_sdp = us_rtpv_make_sdp(_g_rtpv);
|
||||
char *const video_sdp = us_rtpv_make_sdp(_g_rtpv);
|
||||
if (video_sdp == NULL) {
|
||||
PUSH_ERROR(503, "Haven't received SPS/PPS from memsink yet");
|
||||
goto ok_wait;
|
||||
}
|
||||
char *audio_sdp = (_g_rtpa ? us_rtpa_make_sdp(_g_rtpa) : strdup(""));
|
||||
char *const audio_sdp = (_g_rtpa ? us_rtpa_make_sdp(_g_rtpa) : us_strdup(""));
|
||||
US_ASPRINTF(sdp,
|
||||
"v=0" RN
|
||||
"o=- %" PRIu64 " 1 IN IP4 0.0.0.0" RN
|
||||
@@ -442,7 +442,7 @@ static struct janus_plugin_result *_plugin_handle_message(
|
||||
free(audio_sdp);
|
||||
free(video_sdp);
|
||||
}
|
||||
json_t *offer_jsep = json_pack("{ssss}", "type", "offer", "sdp", sdp);
|
||||
json_t *const offer_jsep = json_pack("{ssss}", "type", "offer", "sdp", sdp);
|
||||
free(sdp);
|
||||
PUSH_STATUS("started", offer_jsep);
|
||||
json_decref(offer_jsep);
|
||||
|
||||
@@ -49,7 +49,7 @@ void us_queue_destroy(us_queue_s *queue) {
|
||||
assert(!clock_gettime(CLOCK_MONOTONIC, &m_ts)); \
|
||||
us_ld_to_timespec(us_timespec_to_ld(&m_ts) + timeout, &m_ts); \
|
||||
while (x_var) { \
|
||||
int err = pthread_cond_timedwait(x_cond, &queue->mutex, &m_ts); \
|
||||
const int err = pthread_cond_timedwait(x_cond, &queue->mutex, &m_ts); \
|
||||
if (err == ETIMEDOUT) { \
|
||||
US_MUTEX_UNLOCK(&queue->mutex); \
|
||||
return -1; \
|
||||
@@ -93,7 +93,7 @@ int us_queue_get(us_queue_s *queue, void **item, long double timeout) {
|
||||
|
||||
int us_queue_get_free(us_queue_s *queue) {
|
||||
US_MUTEX_LOCK(&queue->mutex);
|
||||
unsigned size = queue->size;
|
||||
const unsigned size = queue->size;
|
||||
US_MUTEX_UNLOCK(&queue->mutex);
|
||||
return queue->capacity - size;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void us_rtpv_wrap(us_rtpv_s *rtpv, const us_frame_s *frame) {
|
||||
offset += next_start;
|
||||
|
||||
if (last_offset >= 0) {
|
||||
const uint8_t *data = frame->data + last_offset + _PRE;
|
||||
const uint8_t *const data = frame->data + last_offset + _PRE;
|
||||
size_t size = offset - last_offset - _PRE;
|
||||
if (data[size - 1] == 0) { // Check for extra 00
|
||||
--size;
|
||||
@@ -129,7 +129,7 @@ void us_rtpv_wrap(us_rtpv_s *rtpv, const us_frame_s *frame) {
|
||||
}
|
||||
|
||||
if (last_offset >= 0) {
|
||||
const uint8_t *data = frame->data + last_offset + _PRE;
|
||||
const uint8_t *const data = frame->data + last_offset + _PRE;
|
||||
size_t size = frame->used - last_offset - _PRE;
|
||||
_rtpv_process_nalu(rtpv, data, size, pts, true);
|
||||
}
|
||||
@@ -144,7 +144,7 @@ void _rtpv_process_nalu(us_rtpv_s *rtpv, const uint8_t *data, size_t size, uint3
|
||||
case 7: ps = rtpv->sps; break;
|
||||
case 8: ps = rtpv->pps; break;
|
||||
}
|
||||
if (ps) {
|
||||
if (ps != NULL) {
|
||||
US_MUTEX_LOCK(&rtpv->mutex);
|
||||
us_frame_set_data(ps, data, size);
|
||||
US_MUTEX_UNLOCK(&rtpv->mutex);
|
||||
|
||||
@@ -48,7 +48,7 @@ static void _MemsinkObject_destroy_internals(_MemsinkObject *self) {
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
}
|
||||
if (self->frame) {
|
||||
if (self->frame != NULL) {
|
||||
us_frame_destroy(self->frame);
|
||||
self->frame = NULL;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ static PyObject *_MemsinkObject_exit(_MemsinkObject *self, PyObject *Py_UNUSED(i
|
||||
}
|
||||
|
||||
static int _wait_frame(_MemsinkObject *self) {
|
||||
long double deadline_ts = us_get_now_monotonic() + self->wait_timeout;
|
||||
const long double deadline_ts = us_get_now_monotonic() + self->wait_timeout;
|
||||
|
||||
# define RETURN_OS_ERROR { \
|
||||
Py_BLOCK_THREADS \
|
||||
@@ -135,7 +135,7 @@ static int _wait_frame(_MemsinkObject *self) {
|
||||
do {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
||||
int retval = us_flock_timedwait_monotonic(self->fd, self->lock_timeout);
|
||||
const int retval = us_flock_timedwait_monotonic(self->fd, self->lock_timeout);
|
||||
now = us_get_now_monotonic();
|
||||
|
||||
if (retval < 0 && errno != EWOULDBLOCK) {
|
||||
|
||||
@@ -186,7 +186,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
_install_signal_handlers();
|
||||
int retval = abs(_dump_sink(sink_name, sink_timeout, count, interval, &ctx));
|
||||
const int retval = abs(_dump_sink(sink_name, sink_timeout, count, interval, &ctx));
|
||||
if (ctx.v_output && ctx.destroy) {
|
||||
ctx.destroy(ctx.v_output);
|
||||
}
|
||||
@@ -232,7 +232,7 @@ static int _dump_sink(
|
||||
count = -1;
|
||||
}
|
||||
|
||||
useconds_t interval_us = interval * 1000000;
|
||||
const useconds_t interval_us = interval * 1000000;
|
||||
|
||||
us_frame_s *frame = us_frame_init();
|
||||
us_memsink_s *sink = NULL;
|
||||
@@ -272,7 +272,7 @@ static int _dump_sink(
|
||||
}
|
||||
fps_accum += 1;
|
||||
|
||||
if (ctx->v_output) {
|
||||
if (ctx->v_output != NULL) {
|
||||
ctx->write(ctx->v_output, frame);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ void us_base64_encode(const uint8_t *data, size_t size, char **encoded, size_t *
|
||||
OCTET(octet_c);
|
||||
# undef OCTET
|
||||
|
||||
unsigned triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||
const unsigned triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||
|
||||
# define ENCODE(_offset) (*encoded)[encoded_index++] = _ENCODING_TABLE[(triple >> _offset * 6) & 0x3F]
|
||||
ENCODE(3);
|
||||
|
||||
@@ -50,7 +50,7 @@ void us_frame_set_data(us_frame_s *frame, const uint8_t *data, size_t size) {
|
||||
}
|
||||
|
||||
void us_frame_append_data(us_frame_s *frame, const uint8_t *data, size_t size) {
|
||||
size_t new_used = frame->used + size;
|
||||
const size_t new_used = frame->used + size;
|
||||
us_frame_realloc_data(frame, new_used);
|
||||
memcpy(frame->data + frame->used, data, size);
|
||||
frame->used = new_used;
|
||||
|
||||
@@ -40,7 +40,7 @@ us_memsink_s *us_memsink_init(
|
||||
|
||||
US_LOG_INFO("Using %s-sink: %s", name, obj);
|
||||
|
||||
mode_t mask = umask(0);
|
||||
const mode_t mask = umask(0);
|
||||
sink->fd = shm_open(sink->obj, (server ? O_RDWR | O_CREAT : O_RDWR), mode);
|
||||
umask(mask);
|
||||
if (sink->fd == -1) {
|
||||
@@ -107,7 +107,7 @@ bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_clients = (sink->mem->last_client_ts + sink->client_ttl > us_get_now_monotonic());
|
||||
const bool has_clients = (sink->mem->last_client_ts + sink->client_ttl > us_get_now_monotonic());
|
||||
atomic_store(&sink->has_clients, has_clients);
|
||||
|
||||
if (flock(sink->fd, LOCK_UN) < 0) {
|
||||
|
||||
@@ -73,12 +73,12 @@ extern char **environ;
|
||||
|
||||
#ifdef HAS_PDEATHSIG
|
||||
INLINE int us_process_track_parent_death(void) {
|
||||
pid_t parent = getppid();
|
||||
const pid_t parent = getppid();
|
||||
int signum = SIGTERM;
|
||||
# if defined(__linux__)
|
||||
int retval = prctl(PR_SET_PDEATHSIG, signum);
|
||||
const int retval = prctl(PR_SET_PDEATHSIG, signum);
|
||||
# elif defined(__FreeBSD__)
|
||||
int retval = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum);
|
||||
const int retval = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum);
|
||||
# else
|
||||
# error WTF?
|
||||
# endif
|
||||
@@ -91,7 +91,6 @@ INLINE int us_process_track_parent_death(void) {
|
||||
US_LOG_PERROR("The parent process %d is already dead", parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -131,16 +130,14 @@ INLINE void us_process_set_name_prefix(int argc, char *argv[], const char *prefi
|
||||
#endif
|
||||
|
||||
INLINE void us_process_notify_parent(void) {
|
||||
pid_t parent = getppid();
|
||||
|
||||
const pid_t parent = getppid();
|
||||
if (kill(parent, SIGUSR2) < 0) {
|
||||
US_LOG_PERROR("Can't send SIGUSR2 to the parent process %d", parent);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void us_process_suicide(void) {
|
||||
pid_t pid = getpid();
|
||||
|
||||
const pid_t pid = getpid();
|
||||
if (kill(pid, SIGTERM) < 0) {
|
||||
US_LOG_PERROR("Can't send SIGTERM to own pid %d", pid);
|
||||
}
|
||||
|
||||
@@ -104,17 +104,17 @@ INLINE void us_thread_get_name(char *name) { // Always required for logging
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
const pid_t tid = syscall(SYS_gettid);
|
||||
#elif defined(__FreeBSD__)
|
||||
pid_t tid = syscall(SYS_thr_self);
|
||||
const pid_t tid = syscall(SYS_thr_self);
|
||||
#elif defined(__OpenBSD__)
|
||||
pid_t tid = syscall(SYS_getthrid);
|
||||
const pid_t tid = syscall(SYS_getthrid);
|
||||
#elif defined(__NetBSD__)
|
||||
pid_t tid = syscall(SYS__lwp_self);
|
||||
const pid_t tid = syscall(SYS__lwp_self);
|
||||
#elif defined(__DragonFly__)
|
||||
pid_t tid = syscall(SYS_lwp_gettid);
|
||||
const pid_t tid = syscall(SYS_lwp_gettid);
|
||||
#else
|
||||
pid_t tid = 0; // Makes cppcheck happy
|
||||
const pid_t tid = 0; // Makes cppcheck happy
|
||||
# warning gettid() not implemented
|
||||
#endif
|
||||
assert(snprintf(name, US_MAX_THREAD_NAME, "tid=%d", tid) > 0);
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
#define INLINE inline __attribute__((always_inline))
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
#define US_CALLOC(x_dest, x_nmemb) assert(((x_dest) = calloc((x_nmemb), sizeof(*(x_dest)))))
|
||||
#define US_REALLOC(x_dest, x_nmemb) assert(((x_dest) = realloc((x_dest), (x_nmemb) * sizeof(*(x_dest)))))
|
||||
#define US_CALLOC(x_dest, x_nmemb) assert(((x_dest) = calloc((x_nmemb), sizeof(*(x_dest)))) != NULL)
|
||||
#define US_REALLOC(x_dest, x_nmemb) assert(((x_dest) = realloc((x_dest), (x_nmemb) * sizeof(*(x_dest)))) != NULL)
|
||||
#define US_DELETE(x_dest, x_free) { if (x_dest) { x_free(x_dest); } }
|
||||
#define US_MEMSET_ZERO(x_obj) memset(&(x_obj), 0, sizeof(x_obj))
|
||||
|
||||
@@ -63,6 +63,12 @@
|
||||
#define US_ARRAY_LEN(x_array) (sizeof(x_array) / sizeof((x_array)[0]))
|
||||
|
||||
|
||||
INLINE char *us_strdup(const char *str) {
|
||||
char *const new = strdup(str);
|
||||
assert(new != NULL);
|
||||
return new;
|
||||
}
|
||||
|
||||
INLINE const char *us_bool_to_string(bool flag) {
|
||||
return (flag ? "true" : "false");
|
||||
}
|
||||
@@ -131,7 +137,7 @@ INLINE uint64_t us_get_now_monotonic_u64(void) {
|
||||
#undef _X_CLOCK_MONOTONIC
|
||||
|
||||
INLINE uint64_t us_get_now_id(void) {
|
||||
uint64_t now = us_get_now_monotonic_u64();
|
||||
const uint64_t now = us_get_now_monotonic_u64();
|
||||
return (uint64_t)us_triple_u32(now) | ((uint64_t)us_triple_u32(now + 12345) << 32);
|
||||
}
|
||||
|
||||
@@ -162,7 +168,7 @@ INLINE long double us_timespec_to_ld(const struct timespec *ts) {
|
||||
}
|
||||
|
||||
INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) {
|
||||
long double deadline_ts = us_get_now_monotonic() + timeout;
|
||||
const long double deadline_ts = us_get_now_monotonic() + timeout;
|
||||
int retval = -1;
|
||||
|
||||
while (true) {
|
||||
@@ -178,10 +184,10 @@ INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) {
|
||||
}
|
||||
|
||||
INLINE char *us_errno_to_string(int error, char *buf, size_t size) {
|
||||
assert(buf);
|
||||
assert(buf != NULL);
|
||||
assert(size > 0);
|
||||
locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL);
|
||||
char *str = "!!! newlocale() error !!!";
|
||||
const char *str = "!!! newlocale() error !!!";
|
||||
strncpy(buf, (locale ? strerror_l(error, locale) : str), size - 1);
|
||||
buf[size - 1] = '\0';
|
||||
if (locale) {
|
||||
|
||||
@@ -34,7 +34,7 @@ us_frame_s *us_blank_frame_init(const char *path) {
|
||||
blank = _init_external(path);
|
||||
}
|
||||
|
||||
if (blank) {
|
||||
if (blank != NULL) {
|
||||
US_LOG_INFO("Using external blank placeholder: %s", path);
|
||||
} else {
|
||||
blank = _init_internal();
|
||||
@@ -44,7 +44,7 @@ us_frame_s *us_blank_frame_init(const char *path) {
|
||||
}
|
||||
|
||||
static us_frame_s *_init_internal(void) {
|
||||
us_frame_s *blank = us_frame_init();
|
||||
us_frame_s *const blank = us_frame_init();
|
||||
us_frame_set_data(blank, US_BLANK_JPEG_DATA, US_BLANK_JPEG_DATA_SIZE);
|
||||
blank->width = US_BLANK_JPEG_WIDTH;
|
||||
blank->height = US_BLANK_JPEG_HEIGHT;
|
||||
@@ -69,7 +69,7 @@ static us_frame_s *_init_external(const char *path) {
|
||||
us_frame_realloc_data(blank, blank->used + CHUNK_SIZE * 2);
|
||||
}
|
||||
|
||||
size_t readed = fread(blank->data + blank->used, 1, CHUNK_SIZE, fp);
|
||||
const size_t readed = fread(blank->data + blank->used, 1, CHUNK_SIZE, fp);
|
||||
blank->used += readed;
|
||||
|
||||
if (readed < CHUNK_SIZE) {
|
||||
@@ -83,7 +83,7 @@ static us_frame_s *_init_external(const char *path) {
|
||||
}
|
||||
# undef CHUNK_SIZE
|
||||
|
||||
us_frame_s *decoded = us_frame_init();
|
||||
us_frame_s *const decoded = us_frame_init();
|
||||
if (us_unjpeg(blank, decoded, false) < 0) {
|
||||
us_frame_destroy(decoded);
|
||||
goto error;
|
||||
@@ -99,9 +99,7 @@ static us_frame_s *_init_external(const char *path) {
|
||||
blank = NULL;
|
||||
|
||||
ok:
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
US_DELETE(fp, fclose);
|
||||
|
||||
return blank;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ int us_device_open(us_device_s *dev) {
|
||||
void us_device_close(us_device_s *dev) {
|
||||
_RUN(persistent_timeout_reported) = false;
|
||||
|
||||
if (_RUN(hw_bufs)) {
|
||||
if (_RUN(hw_bufs) != NULL) {
|
||||
US_LOG_DEBUG("Releasing device buffers ...");
|
||||
for (unsigned index = 0; index < _RUN(n_bufs); ++index) {
|
||||
# define HW(x_next) _RUN(hw_bufs)[index].x_next
|
||||
@@ -191,9 +191,7 @@ void us_device_close(us_device_s *dev) {
|
||||
}
|
||||
}
|
||||
} else { // V4L2_MEMORY_USERPTR
|
||||
if (HW(raw.data)) {
|
||||
free(HW(raw.data));
|
||||
}
|
||||
US_DELETE(HW(raw.data), free);
|
||||
}
|
||||
|
||||
# undef HW
|
||||
@@ -464,12 +462,9 @@ static int _device_apply_dv_timings(us_device_s *dev) {
|
||||
if (_D_XIOCTL(VIDIOC_QUERY_DV_TIMINGS, &dv) == 0) {
|
||||
if (dv.type == V4L2_DV_BT_656_1120) {
|
||||
// See v4l2_print_dv_timings() in the kernel
|
||||
unsigned htot = V4L2_DV_BT_FRAME_WIDTH(&dv.bt);
|
||||
unsigned vtot = V4L2_DV_BT_FRAME_HEIGHT(&dv.bt);
|
||||
if (dv.bt.interlaced) {
|
||||
vtot /= 2;
|
||||
}
|
||||
unsigned fps = ((htot * vtot) > 0 ? ((100 * (uint64_t)dv.bt.pixelclock)) / (htot * vtot) : 0);
|
||||
const unsigned htot = V4L2_DV_BT_FRAME_WIDTH(&dv.bt);
|
||||
const unsigned vtot = V4L2_DV_BT_FRAME_HEIGHT(&dv.bt) / (dv.bt.interlaced ? 2 : 1);
|
||||
const unsigned fps = ((htot * vtot) > 0 ? ((100 * (uint64_t)dv.bt.pixelclock)) / (htot * vtot) : 0);
|
||||
US_LOG_INFO("Got new DV-timings: %ux%u%s%u.%02u, pixclk=%llu, vsync=%u, hsync=%u",
|
||||
dv.bt.width, dv.bt.height, (dv.bt.interlaced ? "i" : "p"), fps / 100, fps % 100,
|
||||
(unsigned long long)dv.bt.pixelclock, dv.bt.vsync, dv.bt.hsync); // See #11 about %llu
|
||||
@@ -730,7 +725,7 @@ static int _device_open_io_method_userptr(us_device_s *dev) {
|
||||
|
||||
for (_RUN(n_bufs) = 0; _RUN(n_bufs) < req.count; ++_RUN(n_bufs)) {
|
||||
# define HW(x_next) _RUN(hw_bufs)[_RUN(n_bufs)].x_next
|
||||
assert(HW(raw.data) = aligned_alloc(page_size, buf_size));
|
||||
assert((HW(raw.data) = aligned_alloc(page_size, buf_size)) != NULL);
|
||||
memset(HW(raw.data), 0, buf_size);
|
||||
HW(raw.allocated) = buf_size;
|
||||
# undef HW
|
||||
@@ -882,7 +877,7 @@ static const char *_format_to_string_nullable(unsigned format) {
|
||||
}
|
||||
|
||||
static const char *_format_to_string_supported(unsigned format) {
|
||||
const char *format_str = _format_to_string_nullable(format);
|
||||
const char *const format_str = _format_to_string_nullable(format);
|
||||
return (format_str == NULL ? "unsupported" : format_str);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,11 +62,9 @@ us_encoder_s *us_encoder_init(void) {
|
||||
}
|
||||
|
||||
void us_encoder_destroy(us_encoder_s *enc) {
|
||||
if (_ER(m2ms)) {
|
||||
if (_ER(m2ms) != NULL) {
|
||||
for (unsigned index = 0; index < _ER(n_m2ms); ++index) {
|
||||
if (_ER(m2ms[index])) {
|
||||
us_m2m_encoder_destroy(_ER(m2ms[index]));
|
||||
}
|
||||
US_DELETE(_ER(m2ms[index]), us_m2m_encoder_destroy)
|
||||
}
|
||||
free(_ER(m2ms));
|
||||
}
|
||||
@@ -158,10 +156,11 @@ us_workers_pool_s *us_encoder_workers_pool_init(us_encoder_s *enc, us_device_s *
|
||||
}
|
||||
US_MUTEX_UNLOCK(&_ER(mutex));
|
||||
|
||||
long double desired_interval = 0;
|
||||
if (dev->desired_fps > 0 && (dev->desired_fps < dev->run->hw_fps || dev->run->hw_fps == 0)) {
|
||||
desired_interval = (long double)1 / dev->desired_fps;
|
||||
}
|
||||
const long double desired_interval = (
|
||||
dev->desired_fps > 0 && (dev->desired_fps < dev->run->hw_fps || dev->run->hw_fps == 0)
|
||||
? (long double)1 / dev->desired_fps
|
||||
: 0
|
||||
);
|
||||
|
||||
return us_workers_pool_init(
|
||||
"JPEG", "jw", n_workers, desired_interval,
|
||||
|
||||
@@ -61,15 +61,15 @@ typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
unsigned n_m2ms;
|
||||
us_m2m_encoder_s **m2ms;
|
||||
us_m2m_encoder_s **m2ms;
|
||||
} us_encoder_runtime_s;
|
||||
|
||||
typedef struct {
|
||||
us_encoder_type_e type;
|
||||
unsigned n_workers;
|
||||
char *m2m_path;
|
||||
us_encoder_type_e type;
|
||||
unsigned n_workers;
|
||||
char *m2m_path;
|
||||
|
||||
us_encoder_runtime_s *run;
|
||||
us_encoder_runtime_s *run;
|
||||
} us_encoder_s;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -94,10 +94,10 @@ static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame) {
|
||||
if (jpeg->dest == NULL) {
|
||||
assert((jpeg->dest = (struct jpeg_destination_mgr *)(*jpeg->mem->alloc_small)(
|
||||
(j_common_ptr) jpeg, JPOOL_PERMANENT, sizeof(_jpeg_dest_manager_s)
|
||||
)));
|
||||
)) != NULL);
|
||||
}
|
||||
|
||||
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
_jpeg_dest_manager_s *const 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;
|
||||
@@ -123,13 +123,13 @@ static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const
|
||||
uint8_t *ptr = line_buf;
|
||||
|
||||
for (unsigned x = 0; x < frame->width; ++x) {
|
||||
int y = (!z ? data[0] << 8 : data[2] << 8);
|
||||
int u = data[1] - 128;
|
||||
int v = data[3] - 128;
|
||||
const int y = (!z ? data[0] << 8 : data[2] << 8);
|
||||
const int u = data[1] - 128;
|
||||
const int v = data[3] - 128;
|
||||
|
||||
int r = YUV_R(y, u, v);
|
||||
int g = YUV_G(y, u, v);
|
||||
int b = YUV_B(y, u, v);
|
||||
const int r = YUV_R(y, u, v);
|
||||
const int g = YUV_G(y, u, v);
|
||||
const int b = YUV_B(y, u, v);
|
||||
|
||||
*(ptr++) = NORM_COMPONENT(r);
|
||||
*(ptr++) = NORM_COMPONENT(g);
|
||||
@@ -161,13 +161,13 @@ static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const
|
||||
uint8_t *ptr = line_buf;
|
||||
|
||||
for (unsigned x = 0; x < frame->width; ++x) {
|
||||
int y = (!z ? data[1] << 8 : data[3] << 8);
|
||||
int u = data[0] - 128;
|
||||
int v = data[2] - 128;
|
||||
const int y = (!z ? data[1] << 8 : data[3] << 8);
|
||||
const int u = data[0] - 128;
|
||||
const int v = data[2] - 128;
|
||||
|
||||
int r = YUV_R(y, u, v);
|
||||
int g = YUV_G(y, u, v);
|
||||
int b = YUV_B(y, u, v);
|
||||
const int r = YUV_R(y, u, v);
|
||||
const int g = YUV_G(y, u, v);
|
||||
const int b = YUV_B(y, u, v);
|
||||
|
||||
*(ptr++) = NORM_COMPONENT(r);
|
||||
*(ptr++) = NORM_COMPONENT(g);
|
||||
@@ -203,7 +203,7 @@ static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, cons
|
||||
uint8_t *ptr = line_buf;
|
||||
|
||||
for (unsigned x = 0; x < frame->width; ++x) {
|
||||
unsigned int two_byte = (data[1] << 8) + data[0];
|
||||
const unsigned int two_byte = (data[1] << 8) + data[0];
|
||||
|
||||
*(ptr++) = data[1] & 248; // Red
|
||||
*(ptr++) = (uint8_t)((two_byte & 2016) >> 3); // Green
|
||||
@@ -235,12 +235,12 @@ static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const
|
||||
#define JPEG_OUTPUT_BUFFER_SIZE ((size_t)4096)
|
||||
|
||||
static void _jpeg_init_destination(j_compress_ptr jpeg) {
|
||||
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
_jpeg_dest_manager_s *const dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
|
||||
// Allocate the output buffer - it will be released when done with image
|
||||
assert((dest->buf = (JOCTET *)(*jpeg->mem->alloc_small)(
|
||||
(j_common_ptr) jpeg, JPOOL_IMAGE, JPEG_OUTPUT_BUFFER_SIZE * sizeof(JOCTET)
|
||||
)));
|
||||
)) != NULL);
|
||||
|
||||
dest->mgr.next_output_byte = dest->buf;
|
||||
dest->mgr.free_in_buffer = JPEG_OUTPUT_BUFFER_SIZE;
|
||||
@@ -249,7 +249,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
|
||||
|
||||
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
_jpeg_dest_manager_s *const dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
|
||||
us_frame_append_data(dest->frame, dest->buf, JPEG_OUTPUT_BUFFER_SIZE);
|
||||
|
||||
@@ -263,8 +263,8 @@ 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.
|
||||
|
||||
_jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
size_t final = JPEG_OUTPUT_BUFFER_SIZE - dest->mgr.free_in_buffer;
|
||||
_jpeg_dest_manager_s *const dest = (_jpeg_dest_manager_s *)jpeg->dest;
|
||||
const size_t final = JPEG_OUTPUT_BUFFER_SIZE - dest->mgr.free_in_buffer;
|
||||
|
||||
// Write any data remaining in the buffer.
|
||||
us_frame_append_data(dest->frame, dest->buf, final);
|
||||
|
||||
@@ -42,7 +42,7 @@ void _copy_plus_huffman(const us_frame_s *src, us_frame_s *dest) {
|
||||
|
||||
if (!_is_huffman(src->data)) {
|
||||
const uint8_t *src_ptr = src->data;
|
||||
const uint8_t *src_end = src->data + src->used;
|
||||
const uint8_t *const src_end = src->data + src->used;
|
||||
|
||||
while ((((src_ptr[0] << 8) | src_ptr[1]) != 0xFFC0) && (src_ptr < src_end)) {
|
||||
src_ptr += 1;
|
||||
|
||||
@@ -73,7 +73,7 @@ void us_gpio_destroy(void) {
|
||||
_gpio_output_destroy(&us_gpio.prog_running);
|
||||
_gpio_output_destroy(&us_gpio.stream_online);
|
||||
_gpio_output_destroy(&us_gpio.has_http_clients);
|
||||
if (us_gpio.chip) {
|
||||
if (us_gpio.chip != NULL) {
|
||||
gpiod_chip_close(us_gpio.chip);
|
||||
us_gpio.chip = NULL;
|
||||
US_MUTEX_DESTROY(&us_gpio.mutex);
|
||||
@@ -83,8 +83,8 @@ void us_gpio_destroy(void) {
|
||||
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
||||
int retval = 0;
|
||||
|
||||
assert(us_gpio.chip);
|
||||
assert(output->line);
|
||||
assert(us_gpio.chip != NULL);
|
||||
assert(output->line != NULL);
|
||||
assert(output->state != state); // Must be checked in macro for the performance
|
||||
US_MUTEX_LOCK(&us_gpio.mutex);
|
||||
|
||||
@@ -99,7 +99,7 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
||||
}
|
||||
|
||||
static void _gpio_output_init(us_gpio_output_s *output) {
|
||||
assert(us_gpio.chip);
|
||||
assert(us_gpio.chip != NULL);
|
||||
assert(output->line == NULL);
|
||||
|
||||
US_ASPRINTF(output->consumer, "%s::%s", us_gpio.consumer_prefix, output->role);
|
||||
@@ -117,11 +117,11 @@ static void _gpio_output_init(us_gpio_output_s *output) {
|
||||
}
|
||||
|
||||
static void _gpio_output_destroy(us_gpio_output_s *output) {
|
||||
if (output->line) {
|
||||
if (output->line != NULL) {
|
||||
gpiod_line_release(output->line);
|
||||
output->line = NULL;
|
||||
}
|
||||
if (output->consumer) {
|
||||
if (output->consumer != NULL) {
|
||||
free(output->consumer);
|
||||
output->consumer = NULL;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, boo
|
||||
}
|
||||
|
||||
if (us_is_jpeg(frame->format)) {
|
||||
long double now = us_get_now_monotonic();
|
||||
const long double now = us_get_now_monotonic();
|
||||
US_LOG_DEBUG("H264: Input frame is JPEG; decoding ...");
|
||||
if (us_unjpeg(frame, h264->tmp_src, true) < 0) {
|
||||
return;
|
||||
|
||||
@@ -27,8 +27,9 @@ char *us_bufferevent_format_reason(short what) {
|
||||
char *reason;
|
||||
US_CALLOC(reason, 2048);
|
||||
|
||||
// evutil_socket_error_to_string() is not thread-safe
|
||||
char perror_buf[1024] = {0};
|
||||
char *perror_ptr = us_errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024); // evutil_socket_error_to_string() is not thread-safe
|
||||
const char *perror_ptr = us_errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024);
|
||||
bool first = true;
|
||||
|
||||
strcat(reason, perror_ptr);
|
||||
|
||||
@@ -48,12 +48,12 @@ static const struct {
|
||||
|
||||
const char *us_guess_mime_type(const char *path) {
|
||||
// FIXME: false-positive cppcheck
|
||||
char *dot = strrchr(path, '.'); // cppcheck-suppress ctunullpointer
|
||||
const char *dot = strrchr(path, '.'); // cppcheck-suppress ctunullpointer
|
||||
if (dot == NULL || strchr(dot, '/') != NULL) {
|
||||
goto misc;
|
||||
}
|
||||
|
||||
char *ext = dot + 1;
|
||||
const char *ext = dot + 1;
|
||||
for (unsigned index = 0; index < US_ARRAY_LEN(_MIME_TYPES); ++index) {
|
||||
if (!evutil_ascii_strcasecmp(ext, _MIME_TYPES[index].ext)) {
|
||||
return _MIME_TYPES[index].mime;
|
||||
|
||||
@@ -74,7 +74,7 @@ char *us_simplify_request_path(const char *str) {
|
||||
// (out <= str) still true; also now (slash < out)
|
||||
|
||||
if (ch == '/' || ch == '\0') {
|
||||
size_t toklen = out - slash;
|
||||
const size_t toklen = out - slash;
|
||||
|
||||
if (toklen == 3 && pre2 == '.' && pre1 == '.' && *slash == '/') {
|
||||
// "/../" or ("/.." at end of string)
|
||||
|
||||
@@ -46,9 +46,13 @@ static const char *_http_get_header(struct evhttp_request *request, const char *
|
||||
static char *_http_get_client_hostport(struct evhttp_request *request);
|
||||
|
||||
|
||||
#define _RUN(x_next) server->run->x_next
|
||||
#define _A_EVBUFFER_NEW(x_buf) assert((x_buf = evbuffer_new()) != NULL)
|
||||
#define _A_EVBUFFER_ADD(x_buf, x_data, x_size) assert(!evbuffer_add(x_buf, x_data, x_size))
|
||||
#define _A_EVBUFFER_ADD_PRINTF(x_buf, x_fmt, ...) assert(evbuffer_add_printf(x_buf, x_fmt, ##__VA_ARGS__) >= 0)
|
||||
|
||||
#define _RUN(x_next) server->run->x_next
|
||||
#define _STREAM(x_next) _RUN(stream->x_next)
|
||||
#define _VID(x_next) _STREAM(run->video->x_next)
|
||||
#define _VID(x_next) _STREAM(run->video->x_next)
|
||||
#define _EX(x_next) _RUN(exposed->x_next)
|
||||
|
||||
|
||||
@@ -75,19 +79,19 @@ us_server_s *us_server_init(us_stream_s *stream) {
|
||||
server->run = run;
|
||||
|
||||
assert(!evthread_use_pthreads());
|
||||
assert((run->base = event_base_new()));
|
||||
assert((run->http = evhttp_new(run->base)));
|
||||
assert((run->base = event_base_new()) != NULL);
|
||||
assert((run->http = evhttp_new(run->base)) != NULL);
|
||||
evhttp_set_allowed_methods(run->http, EVHTTP_REQ_GET|EVHTTP_REQ_HEAD|EVHTTP_REQ_OPTIONS);
|
||||
return server;
|
||||
}
|
||||
|
||||
void us_server_destroy(us_server_s *server) {
|
||||
if (_RUN(refresher)) {
|
||||
if (_RUN(refresher) != NULL) {
|
||||
event_del(_RUN(refresher));
|
||||
event_free(_RUN(refresher));
|
||||
}
|
||||
|
||||
if (_RUN(request_watcher)) {
|
||||
if (_RUN(request_watcher) != NULL) {
|
||||
event_del(_RUN(request_watcher));
|
||||
event_free(_RUN(request_watcher));
|
||||
}
|
||||
@@ -137,7 +141,7 @@ int us_server_listen(us_server_s *server) {
|
||||
_RUN(last_request_ts) = us_get_now_monotonic();
|
||||
struct timeval interval = {0};
|
||||
interval.tv_usec = 100000;
|
||||
assert((_RUN(request_watcher) = event_new(_RUN(base), -1, EV_PERSIST, _http_request_watcher, server)));
|
||||
assert((_RUN(request_watcher) = event_new(_RUN(base), -1, EV_PERSIST, _http_request_watcher, server)) != NULL);
|
||||
assert(!event_add(_RUN(request_watcher), &interval));
|
||||
}
|
||||
|
||||
@@ -148,7 +152,7 @@ int us_server_listen(us_server_s *server) {
|
||||
} else {
|
||||
interval.tv_usec = 16000; // ~60fps
|
||||
}
|
||||
assert((_RUN(refresher) = event_new(_RUN(base), -1, EV_PERSIST, _http_refresher, server)));
|
||||
assert((_RUN(refresher) = event_new(_RUN(base), -1, EV_PERSIST, _http_refresher, server)) != NULL);
|
||||
assert(!event_add(_RUN(refresher), &interval));
|
||||
}
|
||||
|
||||
@@ -217,8 +221,8 @@ static int _http_preprocess_request(struct evhttp_request *request, us_server_s
|
||||
_RUN(last_request_ts) = us_get_now_monotonic();
|
||||
|
||||
if (server->allow_origin[0] != '\0') {
|
||||
const char *cors_headers = _http_get_header(request, "Access-Control-Request-Headers");
|
||||
const char *cors_method = _http_get_header(request, "Access-Control-Request-Method");
|
||||
const char *const cors_headers = _http_get_header(request, "Access-Control-Request-Headers");
|
||||
const char *const cors_method = _http_get_header(request, "Access-Control-Request-Method");
|
||||
|
||||
ADD_HEADER("Access-Control-Allow-Origin", server->allow_origin);
|
||||
ADD_HEADER("Access-Control-Allow-Credentials", "true");
|
||||
@@ -235,8 +239,8 @@ static int _http_preprocess_request(struct evhttp_request *request, us_server_s
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_RUN(auth_token)) {
|
||||
const char *token = _http_get_header(request, "Authorization");
|
||||
if (_RUN(auth_token) != NULL) {
|
||||
const char *const token = _http_get_header(request, "Authorization");
|
||||
|
||||
if (token == NULL || strcmp(token, _RUN(auth_token)) != 0) {
|
||||
ADD_HEADER("WWW-Authenticate", "Basic realm=\"Restricted area\"");
|
||||
@@ -266,7 +270,7 @@ static int _http_check_run_compat_action(struct evhttp_request *request, void *v
|
||||
int error = 0;
|
||||
|
||||
evhttp_parse_query(evhttp_request_get_uri(request), ¶ms);
|
||||
const char *action = evhttp_find_header(¶ms, "action");
|
||||
const char *const action = evhttp_find_header(¶ms, "action");
|
||||
|
||||
if (action && !strcmp(action, "snapshot")) {
|
||||
_http_callback_snapshot(request, v_server);
|
||||
@@ -289,15 +293,14 @@ static int _http_check_run_compat_action(struct evhttp_request *request, void *v
|
||||
}
|
||||
|
||||
static void _http_callback_root(struct evhttp_request *request, void *v_server) {
|
||||
us_server_s *server = (us_server_s *)v_server;
|
||||
us_server_s *const server = (us_server_s *)v_server;
|
||||
|
||||
PREPROCESS_REQUEST;
|
||||
COMPAT_REQUEST;
|
||||
|
||||
struct evbuffer *buf;
|
||||
|
||||
assert((buf = evbuffer_new()));
|
||||
assert(evbuffer_add_printf(buf, "%s", US_HTML_INDEX_PAGE));
|
||||
_A_EVBUFFER_NEW(buf);
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "%s", US_HTML_INDEX_PAGE);
|
||||
ADD_HEADER("Content-Type", "text/html");
|
||||
evhttp_send_reply(request, HTTP_OK, "OK", buf);
|
||||
|
||||
@@ -305,7 +308,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) {
|
||||
us_server_s *server = (us_server_s *)v_server;
|
||||
us_server_s *const server = (us_server_s *)v_server;
|
||||
|
||||
PREPROCESS_REQUEST;
|
||||
COMPAT_REQUEST;
|
||||
@@ -317,7 +320,7 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server
|
||||
int fd = -1;
|
||||
|
||||
{
|
||||
char *uri_path;
|
||||
const char *uri_path;
|
||||
|
||||
if ((uri = evhttp_uri_parse(evhttp_request_get_uri(request))) == NULL) {
|
||||
goto bad_request;
|
||||
@@ -331,7 +334,7 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server
|
||||
}
|
||||
}
|
||||
|
||||
assert((buf = evbuffer_new()));
|
||||
_A_EVBUFFER_NEW(buf);
|
||||
|
||||
if ((static_path = us_find_static_file_path(server->static_path, decoded_path)) == NULL) {
|
||||
goto not_found;
|
||||
@@ -384,7 +387,7 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server
|
||||
#undef COMPAT_REQUEST
|
||||
|
||||
static void _http_callback_state(struct evhttp_request *request, void *v_server) {
|
||||
us_server_s *server = (us_server_s *)v_server;
|
||||
us_server_s *const server = (us_server_s *)v_server;
|
||||
|
||||
PREPROCESS_REQUEST;
|
||||
|
||||
@@ -393,43 +396,43 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
||||
us_encoder_get_runtime_params(_STREAM(enc), &enc_type, &enc_quality);
|
||||
|
||||
struct evbuffer *buf;
|
||||
assert((buf = evbuffer_new()));
|
||||
_A_EVBUFFER_NEW(buf);
|
||||
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"{\"ok\": true, \"result\": {"
|
||||
" \"encoder\": {\"type\": \"%s\", \"quality\": %u},",
|
||||
us_encoder_type_to_string(enc_type),
|
||||
enc_quality
|
||||
));
|
||||
);
|
||||
|
||||
if (_STREAM(run->h264)) {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
if (_STREAM(run->h264) != NULL) {
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
" \"h264\": {\"bitrate\": %u, \"gop\": %u, \"online\": %s},",
|
||||
_STREAM(h264_bitrate),
|
||||
_STREAM(h264_gop),
|
||||
us_bool_to_string(atomic_load(&_STREAM(run->h264->online)))
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
if (_STREAM(sink) || _STREAM(h264_sink)) {
|
||||
assert(evbuffer_add_printf(buf, " \"sinks\": {"));
|
||||
if (_STREAM(sink)) {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
if (_STREAM(sink) != NULL || _STREAM(h264_sink) != NULL) {
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, " \"sinks\": {");
|
||||
if (_STREAM(sink) != NULL) {
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"\"jpeg\": {\"has_clients\": %s}",
|
||||
us_bool_to_string(atomic_load(&_STREAM(sink->has_clients)))
|
||||
));
|
||||
);
|
||||
}
|
||||
if (_STREAM(h264_sink)) {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
if (_STREAM(h264_sink) != NULL) {
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"%s\"h264\": {\"has_clients\": %s}",
|
||||
(_STREAM(sink) ? ", " : ""),
|
||||
us_bool_to_string(atomic_load(&_STREAM(h264_sink->has_clients)))
|
||||
));
|
||||
);
|
||||
}
|
||||
assert(evbuffer_add_printf(buf, "},"));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "},");
|
||||
}
|
||||
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
" \"source\": {\"resolution\": {\"width\": %u, \"height\": %u},"
|
||||
" \"online\": %s, \"desired_fps\": %u, \"captured_fps\": %u},"
|
||||
" \"stream\": {\"queued_fps\": %u, \"clients\": %u, \"clients_stat\": {",
|
||||
@@ -440,10 +443,10 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
||||
_EX(captured_fps),
|
||||
_EX(queued_fps),
|
||||
_RUN(stream_clients_count)
|
||||
));
|
||||
);
|
||||
|
||||
US_LIST_ITERATE(_RUN(stream_clients), client, {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"\"%" PRIx64 "\": {\"fps\": %u, \"extra_headers\": %s, \"advance_headers\": %s,"
|
||||
" \"dual_final_frames\": %s, \"zero_data\": %s, \"key\": \"%s\"}%s",
|
||||
client->id,
|
||||
@@ -454,10 +457,10 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
||||
us_bool_to_string(client->zero_data),
|
||||
(client->key != NULL ? client->key : "0"),
|
||||
(client->next ? ", " : "")
|
||||
));
|
||||
);
|
||||
});
|
||||
|
||||
assert(evbuffer_add_printf(buf, "}}}}"));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "}}}}");
|
||||
|
||||
ADD_HEADER("Content-Type", "application/json");
|
||||
evhttp_send_reply(request, HTTP_OK, "OK", buf);
|
||||
@@ -465,13 +468,13 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
|
||||
}
|
||||
|
||||
static void _http_callback_snapshot(struct evhttp_request *request, void *v_server) {
|
||||
us_server_s *server = (us_server_s *)v_server;
|
||||
us_server_s *const server = (us_server_s *)v_server;
|
||||
|
||||
PREPROCESS_REQUEST;
|
||||
|
||||
struct evbuffer *buf;
|
||||
assert((buf = evbuffer_new()));
|
||||
assert(!evbuffer_add(buf, (const void *)_EX(frame->data), _EX(frame->used)));
|
||||
_A_EVBUFFER_NEW(buf);
|
||||
_A_EVBUFFER_ADD(buf, (const void *)_EX(frame->data), _EX(frame->used));
|
||||
|
||||
ADD_HEADER("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, pre-check=0, post-check=0, max-age=0");
|
||||
ADD_HEADER("Pragma", "no-cache");
|
||||
@@ -521,14 +524,12 @@ 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
|
||||
|
||||
us_server_s *server = (us_server_s *)v_server;
|
||||
us_server_s *const server = (us_server_s *)v_server;
|
||||
|
||||
PREPROCESS_REQUEST;
|
||||
|
||||
struct evhttp_connection *conn;
|
||||
conn = evhttp_request_get_connection(request);
|
||||
|
||||
if (conn) {
|
||||
struct evhttp_connection *const conn = evhttp_request_get_connection(request);
|
||||
if (conn != NULL) {
|
||||
us_stream_client_s *client;
|
||||
US_CALLOC(client, 1);
|
||||
client->server = server;
|
||||
@@ -562,13 +563,12 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
|
||||
US_LOG_INFO("HTTP: Registered client: %s, id=%" PRIx64 "; clients now: %u",
|
||||
client->hostport, client->id, _RUN(stream_clients_count));
|
||||
|
||||
struct bufferevent *buf_event = evhttp_connection_get_bufferevent(conn);
|
||||
struct bufferevent *const buf_event = evhttp_connection_get_bufferevent(conn);
|
||||
if (server->tcp_nodelay && !_RUN(ext_fd)) {
|
||||
evutil_socket_t fd;
|
||||
int on = 1;
|
||||
|
||||
US_LOG_DEBUG("HTTP: Setting up TCP_NODELAY to the client %s ...", client->hostport);
|
||||
assert((fd = bufferevent_getfd(buf_event)) >= 0);
|
||||
const evutil_socket_t fd = bufferevent_getfd(buf_event);
|
||||
assert(fd >= 0);
|
||||
int on = 1;
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)) != 0) {
|
||||
US_LOG_PERROR("HTTP: Can't set TCP_NODELAY to the client %s", client->hostport);
|
||||
}
|
||||
@@ -585,11 +585,11 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
|
||||
static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_client) {
|
||||
# define BOUNDARY "boundarydonotcross"
|
||||
|
||||
us_stream_client_s *client = (us_stream_client_s *)v_client;
|
||||
us_server_s *server = client->server;
|
||||
us_stream_client_s *const client = (us_stream_client_s *)v_client;
|
||||
us_server_s *const server = client->server;
|
||||
|
||||
long double now = us_get_now_monotonic();
|
||||
long long now_second = us_floor_ms(now);
|
||||
const long double now = us_get_now_monotonic();
|
||||
const long long now_second = us_floor_ms(now);
|
||||
|
||||
if (now_second != client->fps_accum_second) {
|
||||
client->fps = client->fps_accum;
|
||||
@@ -599,7 +599,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
client->fps_accum += 1;
|
||||
|
||||
struct evbuffer *buf;
|
||||
assert((buf = evbuffer_new()));
|
||||
_A_EVBUFFER_NEW(buf);
|
||||
|
||||
// В хроме и его производных есть фундаментальный баг: он отрисовывает
|
||||
// фрейм с задержкой на один, как только ему придут заголовки следующего.
|
||||
@@ -621,30 +621,30 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
// по тем же причинам, по которым у нас нет Content-Length.
|
||||
|
||||
# define ADD_ADVANCE_HEADERS \
|
||||
assert(evbuffer_add_printf(buf, \
|
||||
"Content-Type: image/jpeg" RN "X-Timestamp: %.06Lf" RN RN, us_get_now_real()))
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, \
|
||||
"Content-Type: image/jpeg" RN "X-Timestamp: %.06Lf" RN RN, us_get_now_real())
|
||||
|
||||
if (client->need_initial) {
|
||||
assert(evbuffer_add_printf(buf, "HTTP/1.0 200 OK" RN));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "HTTP/1.0 200 OK" RN);
|
||||
|
||||
if (client->server->allow_origin[0] != '\0') {
|
||||
const char *cors_headers = _http_get_header(client->request, "Access-Control-Request-Headers");
|
||||
const char *cors_method = _http_get_header(client->request, "Access-Control-Request-Method");
|
||||
const char *const cors_headers = _http_get_header(client->request, "Access-Control-Request-Headers");
|
||||
const char *const cors_method = _http_get_header(client->request, "Access-Control-Request-Method");
|
||||
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"Access-Control-Allow-Origin: %s" RN
|
||||
"Access-Control-Allow-Credentials: true" RN,
|
||||
client->server->allow_origin
|
||||
));
|
||||
);
|
||||
if (cors_headers != NULL) {
|
||||
assert(evbuffer_add_printf(buf, "Access-Control-Allow-Headers: %s" RN, cors_headers));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "Access-Control-Allow-Headers: %s" RN, cors_headers);
|
||||
}
|
||||
if (cors_method != NULL) {
|
||||
assert(evbuffer_add_printf(buf, "Access-Control-Allow-Methods: %s" RN, cors_method));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, "Access-Control-Allow-Methods: %s" RN, cors_method);
|
||||
}
|
||||
}
|
||||
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, pre-check=0, post-check=0, max-age=0" RN
|
||||
"Pragma: no-cache" RN
|
||||
"Expires: Mon, 3 Jan 2000 12:34:56 GMT" RN
|
||||
@@ -654,7 +654,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
"--" BOUNDARY RN,
|
||||
(client->key != NULL ? client->key : "0"),
|
||||
client->id
|
||||
));
|
||||
);
|
||||
|
||||
if (client->advance_headers) {
|
||||
ADD_ADVANCE_HEADERS;
|
||||
@@ -665,7 +665,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
}
|
||||
|
||||
if (!client->advance_headers) {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"Content-Type: image/jpeg" RN
|
||||
"Content-Length: %zu" RN
|
||||
"X-Timestamp: %.06Lf" RN
|
||||
@@ -673,9 +673,9 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
(!client->zero_data ? _EX(frame->used) : 0),
|
||||
us_get_now_real(),
|
||||
(client->extra_headers ? "" : RN)
|
||||
));
|
||||
);
|
||||
if (client->extra_headers) {
|
||||
assert(evbuffer_add_printf(buf,
|
||||
_A_EVBUFFER_ADD_PRINTF(buf,
|
||||
"X-UStreamer-Online: %s" RN
|
||||
"X-UStreamer-Dropped: %u" RN
|
||||
"X-UStreamer-Width: %u" RN
|
||||
@@ -703,14 +703,14 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
|
||||
_EX(expose_end_ts),
|
||||
now,
|
||||
now - _EX(frame->grab_ts)
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!client->zero_data) {
|
||||
assert(!evbuffer_add(buf, (void *)_EX(frame->data), _EX(frame->used)));
|
||||
_A_EVBUFFER_ADD(buf, (void *)_EX(frame->data), _EX(frame->used));
|
||||
}
|
||||
assert(evbuffer_add_printf(buf, RN "--" BOUNDARY RN));
|
||||
_A_EVBUFFER_ADD_PRINTF(buf, RN "--" BOUNDARY RN);
|
||||
|
||||
if (client->advance_headers) {
|
||||
ADD_ADVANCE_HEADERS;
|
||||
@@ -727,8 +727,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) {
|
||||
us_stream_client_s *client = (us_stream_client_s *)v_client;
|
||||
us_server_s *server = client->server;
|
||||
us_stream_client_s *const client = (us_stream_client_s *)v_client;
|
||||
us_server_s *const server = client->server;
|
||||
|
||||
US_LIST_REMOVE_C(_RUN(stream_clients), client, _RUN(stream_clients_count));
|
||||
|
||||
@@ -739,15 +739,13 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN
|
||||
# endif
|
||||
}
|
||||
|
||||
char *reason = us_bufferevent_format_reason(what);
|
||||
char *const reason = us_bufferevent_format_reason(what);
|
||||
US_LOG_INFO("HTTP: Disconnected client: %s, id=%" PRIx64 ", %s; clients now: %u",
|
||||
client->hostport, client->id, reason, _RUN(stream_clients_count));
|
||||
free(reason);
|
||||
|
||||
struct evhttp_connection *conn = evhttp_request_get_connection(client->request);
|
||||
if (conn) {
|
||||
evhttp_connection_free(conn);
|
||||
}
|
||||
struct evhttp_connection *const conn = evhttp_request_get_connection(client->request);
|
||||
US_DELETE(conn, evhttp_connection_free);
|
||||
|
||||
free(client->key);
|
||||
free(client->hostport);
|
||||
@@ -759,15 +757,15 @@ static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bo
|
||||
bool queued = false;
|
||||
|
||||
US_LIST_ITERATE(_RUN(stream_clients), client, {
|
||||
struct evhttp_connection *conn = evhttp_request_get_connection(client->request);
|
||||
if (conn) {
|
||||
struct evhttp_connection *const conn = evhttp_request_get_connection(client->request);
|
||||
if (conn != NULL) {
|
||||
// Фикс для бага WebKit. При включенной опции дропа одинаковых фреймов,
|
||||
// WebKit отрисовывает последний фрейм в серии с некоторой задержкой,
|
||||
// и нужно послать два фрейма, чтобы серия была вовремя завершена.
|
||||
// Это похоже на баг Blink (см. _http_callback_stream_write() и advance_headers),
|
||||
// но фикс для него не лечит проблему вебкита. Такие дела.
|
||||
|
||||
bool dual_update = (
|
||||
const bool dual_update = (
|
||||
server->drop_same_frames
|
||||
&& client->dual_final_frames
|
||||
&& stream_updated
|
||||
@@ -776,7 +774,7 @@ static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bo
|
||||
);
|
||||
|
||||
if (dual_update || frame_updated || client->need_first_frame) {
|
||||
struct bufferevent *buf_event = evhttp_connection_get_bufferevent(conn);
|
||||
struct bufferevent *const buf_event = evhttp_connection_get_bufferevent(conn);
|
||||
bufferevent_setcb(buf_event, NULL, _http_callback_stream_write, _http_callback_stream_error, (void *)client);
|
||||
bufferevent_enable(buf_event, EV_READ|EV_WRITE);
|
||||
|
||||
@@ -794,7 +792,7 @@ static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bo
|
||||
if (queued) {
|
||||
static unsigned queued_fps_accum = 0;
|
||||
static long long queued_fps_second = 0;
|
||||
long long now = us_floor_ms(us_get_now_monotonic());
|
||||
const long long now = us_floor_ms(us_get_now_monotonic());
|
||||
if (now != queued_fps_second) {
|
||||
_EX(queued_fps) = queued_fps_accum;
|
||||
queued_fps_accum = 0;
|
||||
@@ -909,16 +907,16 @@ static char *_http_get_client_hostport(struct evhttp_request *request) {
|
||||
char *addr = NULL;
|
||||
unsigned short port = 0;
|
||||
struct evhttp_connection *conn = evhttp_request_get_connection(request);
|
||||
if (conn) {
|
||||
if (conn != NULL) {
|
||||
char *peer;
|
||||
evhttp_connection_get_peer(conn, &peer, &port);
|
||||
assert(addr = strdup(peer));
|
||||
addr = us_strdup(peer);
|
||||
}
|
||||
|
||||
const char *xff = _http_get_header(request, "X-Forwarded-For");
|
||||
if (xff) {
|
||||
if (xff != NULL) {
|
||||
US_DELETE(addr, free);
|
||||
assert(addr = strndup(xff, 1024));
|
||||
assert((addr = strndup(xff, 1024)) != NULL);
|
||||
for (unsigned index = 0; addr[index]; ++index) {
|
||||
if (addr[index] == ',') {
|
||||
addr[index] = '\0';
|
||||
@@ -928,7 +926,7 @@ static char *_http_get_client_hostport(struct evhttp_request *request) {
|
||||
}
|
||||
|
||||
if (addr == NULL) {
|
||||
assert(addr = strdup("???"));
|
||||
addr = us_strdup("???");
|
||||
}
|
||||
|
||||
char *hostport;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
char *us_find_static_file_path(const char *root_path, const char *request_path) {
|
||||
char *path = NULL;
|
||||
|
||||
char *simplified_path = us_simplify_request_path(request_path);
|
||||
char *const simplified_path = us_simplify_request_path(request_path);
|
||||
if (simplified_path[0] == '\0') {
|
||||
US_LOG_VERBOSE("HTTP: Invalid request path %s to static", request_path);
|
||||
goto error;
|
||||
@@ -65,9 +65,7 @@ char *us_find_static_file_path(const char *root_path, const char *request_path)
|
||||
goto ok;
|
||||
|
||||
error:
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
US_DELETE(path, free);
|
||||
path = NULL;
|
||||
|
||||
ok:
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
|
||||
evutil_socket_t us_evhttp_bind_systemd(struct evhttp *http) {
|
||||
int fds = sd_listen_fds(1);
|
||||
const int fds = sd_listen_fds(1);
|
||||
if (fds < 1) {
|
||||
US_LOG_ERROR("No available systemd sockets");
|
||||
return -1;
|
||||
|
||||
@@ -38,8 +38,8 @@ evutil_socket_t us_evhttp_bind_unix(struct evhttp *http, const char *path, bool
|
||||
|
||||
# undef MAX_SUN_PATH
|
||||
|
||||
evutil_socket_t fd = -1;
|
||||
assert((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
|
||||
const evutil_socket_t fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
assert(fd >= 0);
|
||||
assert(!evutil_make_socket_nonblocking(fd));
|
||||
|
||||
if (rm && unlink(path) < 0) {
|
||||
|
||||
@@ -38,7 +38,7 @@ bool us_uri_get_true(struct evkeyvalq *params, const char *key) {
|
||||
}
|
||||
|
||||
char *us_uri_get_string(struct evkeyvalq *params, const char *key) {
|
||||
const char *value_str = evhttp_find_header(params, key);
|
||||
const char *const value_str = evhttp_find_header(params, key);
|
||||
if (value_str != NULL) {
|
||||
return evhttp_encode_uri(value_str);
|
||||
}
|
||||
|
||||
@@ -126,11 +126,11 @@ static us_m2m_encoder_s *_m2m_encoder_init(
|
||||
|
||||
us_m2m_encoder_s *enc;
|
||||
US_CALLOC(enc, 1);
|
||||
assert(enc->name = strdup(name));
|
||||
enc->name = us_strdup(name);
|
||||
if (path == NULL) {
|
||||
assert(enc->path = strdup(output_format == V4L2_PIX_FMT_JPEG ? "/dev/video31" : "/dev/video11"));
|
||||
enc->path = us_strdup(output_format == V4L2_PIX_FMT_JPEG ? "/dev/video31" : "/dev/video11");
|
||||
} else {
|
||||
assert(enc->path = strdup(path));
|
||||
enc->path = us_strdup(path);
|
||||
}
|
||||
enc->output_format = output_format;
|
||||
enc->fps = fps;
|
||||
@@ -150,7 +150,7 @@ static us_m2m_encoder_s *_m2m_encoder_init(
|
||||
}
|
||||
|
||||
static void _m2m_encoder_prepare(us_m2m_encoder_s *enc, const us_frame_s *frame) {
|
||||
bool dma = (enc->allow_dma && frame->dma_fd >= 0);
|
||||
const bool dma = (enc->allow_dma && frame->dma_fd >= 0);
|
||||
|
||||
_E_LOG_INFO("Configuring encoder: DMA=%d ...", dma);
|
||||
|
||||
@@ -312,7 +312,7 @@ static int _m2m_encoder_init_buffers(
|
||||
MAP_SHARED,
|
||||
_RUN(fd),
|
||||
plane.m.mem_offset
|
||||
)) == NULL) {
|
||||
)) == MAP_FAILED) {
|
||||
_E_LOG_PERROR("Can't map %s buffer=%u", name, *n_bufs_ptr);
|
||||
goto error;
|
||||
}
|
||||
@@ -346,7 +346,7 @@ static void _m2m_encoder_cleanup(us_m2m_encoder_s *enc) {
|
||||
}
|
||||
|
||||
# define DESTROY_BUFFERS(x_name, x_target) { \
|
||||
if (_RUN(x_target##_bufs)) { \
|
||||
if (_RUN(x_target##_bufs) != NULL) { \
|
||||
for (unsigned m_index = 0; m_index < _RUN(n_##x_target##_bufs); ++m_index) { \
|
||||
if (_RUN(x_target##_bufs[m_index].allocated) > 0 && _RUN(x_target##_bufs[m_index].data) != NULL) { \
|
||||
if (munmap(_RUN(x_target##_bufs[m_index].data), _RUN(x_target##_bufs[m_index].allocated)) < 0) { \
|
||||
@@ -415,7 +415,7 @@ static int _m2m_encoder_compress_raw(us_m2m_encoder_s *enc, const us_frame_s *sr
|
||||
_E_LOG_DEBUG("Grabbed INPUT buffer=%u", input_buf.index);
|
||||
}
|
||||
|
||||
uint64_t now = us_get_now_monotonic_u64();
|
||||
const uint64_t now = us_get_now_monotonic_u64();
|
||||
struct timeval ts = {
|
||||
.tv_sec = now / 1000000,
|
||||
.tv_usec = now % 1000000,
|
||||
|
||||
@@ -241,7 +241,7 @@ us_options_s *us_options_init(unsigned argc, char *argv[]) {
|
||||
|
||||
US_CALLOC(options->argv_copy, argc);
|
||||
for (unsigned index = 0; index < argc; ++index) {
|
||||
assert(options->argv_copy[index] = strdup(argv[index]));
|
||||
options->argv_copy[index] = us_strdup(argv[index]);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
|
||||
}
|
||||
|
||||
# define OPT_NUMBER(x_name, x_dest, x_min, x_max, x_base) { \
|
||||
errno = 0; char *m_end = NULL; long long m_tmp = strtoll(optarg, &m_end, x_base); \
|
||||
errno = 0; char *m_end = NULL; const long long m_tmp = strtoll(optarg, &m_end, x_base); \
|
||||
if (errno || *m_end || m_tmp < x_min || m_tmp > x_max) { \
|
||||
printf("Invalid value for '%s=%s': min=%lld, max=%lld\n", x_name, optarg, (long long)x_min, (long long)x_max); \
|
||||
return -1; \
|
||||
|
||||
@@ -77,12 +77,12 @@ void us_stream_destroy(us_stream_s *stream) {
|
||||
}
|
||||
|
||||
void us_stream_loop(us_stream_s *stream) {
|
||||
assert(stream->blank);
|
||||
assert(stream->blank != NULL);
|
||||
|
||||
US_LOG_INFO("Using V4L2 device: %s", stream->dev->path);
|
||||
US_LOG_INFO("Using desired FPS: %u", stream->dev->desired_fps);
|
||||
|
||||
if (stream->h264_sink) {
|
||||
if (stream->h264_sink != NULL) {
|
||||
_RUN(h264) = us_h264_stream_init(stream->h264_sink, stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop);
|
||||
}
|
||||
|
||||
@@ -99,10 +99,10 @@ void us_stream_loop(us_stream_s *stream) {
|
||||
US_SEP_DEBUG('-');
|
||||
US_LOG_DEBUG("Waiting for worker ...");
|
||||
|
||||
us_worker_s *ready_wr = us_workers_pool_wait(pool);
|
||||
us_encoder_job_s *ready_job = (us_encoder_job_s *)(ready_wr->job);
|
||||
us_worker_s *const ready_wr = us_workers_pool_wait(pool);
|
||||
us_encoder_job_s *const ready_job = (us_encoder_job_s *)(ready_wr->job);
|
||||
|
||||
if (ready_job->hw) {
|
||||
if (ready_job->hw != NULL) {
|
||||
if (us_device_release_buffer(stream->dev, ready_job->hw) < 0) {
|
||||
ready_wr->job_failed = true;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ void us_stream_loop(us_stream_s *stream) {
|
||||
bool has_read;
|
||||
bool has_write;
|
||||
bool has_error;
|
||||
int selected = us_device_select(stream->dev, &has_read, &has_write, &has_error);
|
||||
const int selected = us_device_select(stream->dev, &has_read, &has_write, &has_error);
|
||||
|
||||
if (selected < 0) {
|
||||
if (errno != EINTR) {
|
||||
@@ -160,7 +160,7 @@ void us_stream_loop(us_stream_s *stream) {
|
||||
const long long now_second = us_floor_ms(now);
|
||||
|
||||
us_hw_buffer_s *hw;
|
||||
int buf_index = us_device_grab_buffer(stream->dev, &hw);
|
||||
const int buf_index = us_device_grab_buffer(stream->dev, &hw);
|
||||
|
||||
if (buf_index >= 0) {
|
||||
if (now < grab_after) {
|
||||
@@ -220,9 +220,7 @@ void us_stream_loop(us_stream_s *stream) {
|
||||
# endif
|
||||
}
|
||||
|
||||
if (_RUN(h264)) {
|
||||
us_h264_stream_destroy(_RUN(h264));
|
||||
}
|
||||
US_DELETE(_RUN(h264), us_h264_stream_destroy);
|
||||
}
|
||||
|
||||
void us_stream_loop_break(us_stream_s *stream) {
|
||||
@@ -299,7 +297,7 @@ static void _stream_expose_frame(us_stream_s *stream, us_frame_s *frame, unsigne
|
||||
|
||||
US_MUTEX_LOCK(&VID(mutex));
|
||||
|
||||
if (frame) {
|
||||
if (frame != NULL) {
|
||||
new = frame;
|
||||
_RUN(last_as_blank_ts) = 0; // Останавливаем таймер
|
||||
US_LOG_DEBUG("Exposed ALIVE video frame");
|
||||
@@ -336,10 +334,10 @@ static void _stream_expose_frame(us_stream_s *stream, us_frame_s *frame, unsigne
|
||||
}
|
||||
}
|
||||
|
||||
if (new) {
|
||||
if (new != NULL) {
|
||||
us_frame_copy(new, VID(frame));
|
||||
}
|
||||
VID(frame->online) = (bool)frame;
|
||||
VID(frame->online) = (frame != NULL);
|
||||
VID(captured_fps) = captured_fps;
|
||||
atomic_store(&VID(updated), true);
|
||||
|
||||
|
||||
@@ -134,10 +134,10 @@ void us_workers_pool_assign(us_workers_pool_s *pool, us_worker_s *ready_wr/*, vo
|
||||
pool->oldest_wr = ready_wr;
|
||||
pool->latest_wr = pool->oldest_wr;
|
||||
} else {
|
||||
if (ready_wr->next_wr) {
|
||||
if (ready_wr->next_wr != NULL) {
|
||||
ready_wr->next_wr->prev_wr = ready_wr->prev_wr;
|
||||
}
|
||||
if (ready_wr->prev_wr) {
|
||||
if (ready_wr->prev_wr != NULL) {
|
||||
ready_wr->prev_wr->next_wr = ready_wr->next_wr;
|
||||
}
|
||||
ready_wr->prev_wr = pool->latest_wr;
|
||||
@@ -189,7 +189,7 @@ static void *_worker_thread(void *v_worker) {
|
||||
US_MUTEX_UNLOCK(&wr->has_job_mutex);
|
||||
|
||||
if (!atomic_load(&wr->pool->stop)) {
|
||||
long double job_start_ts = us_get_now_monotonic();
|
||||
const long double job_start_ts = us_get_now_monotonic();
|
||||
wr->job_failed = !wr->pool->run_job(wr);
|
||||
if (!wr->job_failed) {
|
||||
wr->job_start_ts = job_start_ts;
|
||||
|
||||
Reference in New Issue
Block a user