diff --git a/janus/src/audio.c b/janus/src/audio.c index 472defc..62f508f 100644 --- a/janus/src/audio.c +++ b/janus/src/audio.c @@ -23,29 +23,29 @@ #include "audio.h" -#define JLOG_PERROR_ALSA(_err, _prefix, _msg, ...) JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, snd_strerror(_err)) -#define JLOG_PERROR_RES(_err, _prefix, _msg, ...) JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, speex_resampler_strerror(_err)) -#define JLOG_PERROR_OPUS(_err, _prefix, _msg, ...) JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, opus_strerror(_err)) +#define _JLOG_PERROR_ALSA(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, snd_strerror(_err)) +#define _JLOG_PERROR_RES(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, speex_resampler_strerror(_err)) +#define _JLOG_PERROR_OPUS(_err, _prefix, _msg, ...) US_JLOG_ERROR(_prefix, _msg ": %s", ##__VA_ARGS__, opus_strerror(_err)) // A number of frames per 1 channel: // - https://github.com/xiph/opus/blob/7b05f44/src/opus_demo.c#L368 -#define HZ_TO_FRAMES(_hz) (6 * (_hz) / 50) // 120ms -#define HZ_TO_BUF16(_hz) (HZ_TO_FRAMES(_hz) * 2) // One stereo frame = (16bit L) + (16bit R) -#define HZ_TO_BUF8(_hz) (HZ_TO_BUF16(_hz) * sizeof(int16_t)) +#define _HZ_TO_FRAMES(_hz) (6 * (_hz) / 50) // 120ms +#define _HZ_TO_BUF16(_hz) (_HZ_TO_FRAMES(_hz) * 2) // One stereo frame = (16bit L) + (16bit R) +#define _HZ_TO_BUF8(_hz) (_HZ_TO_BUF16(_hz) * sizeof(int16_t)) -#define MIN_PCM_HZ 8000 -#define MAX_PCM_HZ 192000 -#define MAX_BUF16 HZ_TO_BUF16(MAX_PCM_HZ) -#define MAX_BUF8 HZ_TO_BUF8(MAX_PCM_HZ) -#define ENCODER_INPUT_HZ 48000 +#define _MIN_PCM_HZ 8000 +#define _MAX_PCM_HZ 192000 +#define _MAX_BUF16 _HZ_TO_BUF16(_MAX_PCM_HZ) +#define _MAX_BUF8 _HZ_TO_BUF8(_MAX_PCM_HZ) +#define _ENCODER_INPUT_HZ 48000 typedef struct { - int16_t data[MAX_BUF16]; + int16_t data[_MAX_BUF16]; } _pcm_buffer_s; typedef struct { - uint8_t data[MAX_BUF8]; // Worst case + uint8_t data[_MAX_BUF8]; // Worst case size_t used; uint64_t pts; } _enc_buffer_s; @@ -55,12 +55,12 @@ static void *_pcm_thread(void *v_audio); static void *_encoder_thread(void *v_audio); -audio_s *audio_init(const char *name, unsigned pcm_hz) { - audio_s *audio; - A_CALLOC(audio, 1); +us_audio_s *us_audio_init(const char *name, unsigned pcm_hz) { + us_audio_s *audio; + US_CALLOC(audio, 1); audio->pcm_hz = pcm_hz; - audio->pcm_queue = queue_init(8); - audio->enc_queue = queue_init(8); + audio->pcm_queue = us_queue_init(8); + audio->enc_queue = us_queue_init(8); atomic_init(&audio->stop, false); int err; @@ -68,14 +68,14 @@ audio_s *audio_init(const char *name, unsigned pcm_hz) { { if ((err = snd_pcm_open(&audio->pcm, name, SND_PCM_STREAM_CAPTURE, 0)) < 0) { audio->pcm = NULL; - JLOG_PERROR_ALSA(err, "audio", "Can't open PCM capture"); + _JLOG_PERROR_ALSA(err, "audio", "Can't open PCM capture"); goto error; } assert(!snd_pcm_hw_params_malloc(&audio->pcm_params)); # define SET_PARAM(_msg, _func, ...) { \ if ((err = _func(audio->pcm, audio->pcm_params, ##__VA_ARGS__)) < 0) { \ - JLOG_PERROR_ALSA(err, "audio", _msg); \ + _JLOG_PERROR_ALSA(err, "audio", _msg); \ goto error; \ } \ } @@ -85,30 +85,30 @@ audio_s *audio_init(const char *name, unsigned pcm_hz) { SET_PARAM("Can't set PCM channels numbre", snd_pcm_hw_params_set_channels, 2); SET_PARAM("Can't set PCM sampling format", snd_pcm_hw_params_set_format, SND_PCM_FORMAT_S16_LE); SET_PARAM("Can't set PCM sampling rate", snd_pcm_hw_params_set_rate_near, &audio->pcm_hz, 0); - if (audio->pcm_hz < MIN_PCM_HZ || audio->pcm_hz > MAX_PCM_HZ) { - JLOG_ERROR("audio", "Unsupported PCM freq: %u; should be: %u <= F <= %u", - audio->pcm_hz, MIN_PCM_HZ, MAX_PCM_HZ); + if (audio->pcm_hz < _MIN_PCM_HZ || audio->pcm_hz > _MAX_PCM_HZ) { + US_JLOG_ERROR("audio", "Unsupported PCM freq: %u; should be: %u <= F <= %u", + audio->pcm_hz, _MIN_PCM_HZ, _MAX_PCM_HZ); goto error; } - audio->pcm_frames = HZ_TO_FRAMES(audio->pcm_hz); - audio->pcm_size = HZ_TO_BUF8(audio->pcm_hz); + audio->pcm_frames = _HZ_TO_FRAMES(audio->pcm_hz); + audio->pcm_size = _HZ_TO_BUF8(audio->pcm_hz); SET_PARAM("Can't apply PCM params", snd_pcm_hw_params); # undef SET_PARAM } - if (audio->pcm_hz != ENCODER_INPUT_HZ) { - audio->res = speex_resampler_init(2, audio->pcm_hz, ENCODER_INPUT_HZ, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err); + if (audio->pcm_hz != _ENCODER_INPUT_HZ) { + audio->res = speex_resampler_init(2, audio->pcm_hz, _ENCODER_INPUT_HZ, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err); if (err < 0) { audio->res = NULL; - JLOG_PERROR_RES(err, "audio", "Can't create resampler"); + _JLOG_PERROR_RES(err, "audio", "Can't create resampler"); goto error; } } { // OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY - audio->enc = opus_encoder_create(ENCODER_INPUT_HZ, 2, OPUS_APPLICATION_AUDIO, &err); + audio->enc = opus_encoder_create(_ENCODER_INPUT_HZ, 2, OPUS_APPLICATION_AUDIO, &err); assert(err == 0); assert(!opus_encoder_ctl(audio->enc, OPUS_SET_BITRATE(48000))); assert(!opus_encoder_ctl(audio->enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND))); @@ -116,23 +116,23 @@ audio_s *audio_init(const char *name, unsigned pcm_hz) { // OPUS_SET_INBAND_FEC(1), OPUS_SET_PACKET_LOSS_PERC(10): see rtpa.c } - JLOG_INFO("audio", "Pipeline configured on %uHz; capturing ...", audio->pcm_hz); + US_JLOG_INFO("audio", "Pipeline configured on %uHz; capturing ...", audio->pcm_hz); audio->tids_created = true; - A_THREAD_CREATE(&audio->enc_tid, _encoder_thread, audio); - A_THREAD_CREATE(&audio->pcm_tid, _pcm_thread, audio); + US_THREAD_CREATE(&audio->enc_tid, _encoder_thread, audio); + US_THREAD_CREATE(&audio->pcm_tid, _pcm_thread, audio); return audio; error: - audio_destroy(audio); + us_audio_destroy(audio); return NULL; } -void audio_destroy(audio_s *audio) { +void us_audio_destroy(us_audio_s *audio) { if (audio->tids_created) { atomic_store(&audio->stop, true); - A_THREAD_JOIN(audio->pcm_tid); - A_THREAD_JOIN(audio->enc_tid); + US_THREAD_JOIN(audio->pcm_tid); + US_THREAD_JOIN(audio->enc_tid); } if (audio->enc) { opus_encoder_destroy(audio->enc); @@ -146,20 +146,20 @@ void audio_destroy(audio_s *audio) { if (audio->pcm_params) { snd_pcm_hw_params_free(audio->pcm_params); } - QUEUE_FREE_ITEMS_AND_DESTROY(audio->enc_queue, free); - QUEUE_FREE_ITEMS_AND_DESTROY(audio->pcm_queue, free); + US_QUEUE_FREE_ITEMS_AND_DESTROY(audio->enc_queue, free); + US_QUEUE_FREE_ITEMS_AND_DESTROY(audio->pcm_queue, free); if (audio->tids_created) { - JLOG_INFO("audio", "Pipeline closed"); + US_JLOG_INFO("audio", "Pipeline closed"); } free(audio); } -int audio_get_encoded(audio_s *audio, uint8_t *data, size_t *size, uint64_t *pts) { +int us_audio_get_encoded(us_audio_s *audio, uint8_t *data, size_t *size, uint64_t *pts) { if (atomic_load(&audio->stop)) { return -1; } _enc_buffer_s *buf; - if (!queue_get(audio->enc_queue, (void **)&buf, 0.1)) { + if (!us_queue_get(audio->enc_queue, (void **)&buf, 0.1)) { if (*size < buf->used) { free(buf); return -3; @@ -174,28 +174,28 @@ int audio_get_encoded(audio_s *audio, uint8_t *data, size_t *size, uint64_t *pts } static void *_pcm_thread(void *v_audio) { - A_THREAD_RENAME("us_a_pcm"); + US_THREAD_RENAME("us_a_pcm"); - audio_s *audio = (audio_s *)v_audio; - uint8_t in[MAX_BUF8]; + us_audio_s *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); if (frames < 0) { - JLOG_PERROR_ALSA(frames, "audio", "Fatal: Can't capture PCM frames"); + _JLOG_PERROR_ALSA(frames, "audio", "Fatal: Can't capture PCM frames"); break; } else if (frames < (int)audio->pcm_frames) { - JLOG_ERROR("audio", "Fatal: Too few PCM frames captured"); + US_JLOG_ERROR("audio", "Fatal: Too few PCM frames captured"); break; } - if (queue_get_free(audio->pcm_queue)) { + if (us_queue_get_free(audio->pcm_queue)) { _pcm_buffer_s *out; - A_CALLOC(out, 1); + US_CALLOC(out, 1); memcpy(out->data, in, audio->pcm_size); - assert(!queue_put(audio->pcm_queue, out, 0)); + assert(!us_queue_put(audio->pcm_queue, out, 0)); } else { - JLOG_ERROR("audio", "PCM queue is full"); + US_JLOG_ERROR("audio", "PCM queue is full"); } } @@ -204,42 +204,42 @@ static void *_pcm_thread(void *v_audio) { } static void *_encoder_thread(void *v_audio) { - A_THREAD_RENAME("us_a_enc"); + US_THREAD_RENAME("us_a_enc"); - audio_s *audio = (audio_s *)v_audio; - int16_t in_res[MAX_BUF16]; + us_audio_s *audio = (us_audio_s *)v_audio; + int16_t in_res[_MAX_BUF16]; while (!atomic_load(&audio->stop)) { _pcm_buffer_s *in; - if (!queue_get(audio->pcm_queue, (void **)&in, 0.1)) { + if (!us_queue_get(audio->pcm_queue, (void **)&in, 0.1)) { int16_t *in_ptr; if (audio->res) { - assert(audio->pcm_hz != ENCODER_INPUT_HZ); + assert(audio->pcm_hz != _ENCODER_INPUT_HZ); uint32_t in_count = audio->pcm_frames; - uint32_t out_count = HZ_TO_FRAMES(ENCODER_INPUT_HZ); + uint32_t out_count = _HZ_TO_FRAMES(_ENCODER_INPUT_HZ); speex_resampler_process_interleaved_int(audio->res, in->data, &in_count, in_res, &out_count); in_ptr = in_res; } else { - assert(audio->pcm_hz == ENCODER_INPUT_HZ); + assert(audio->pcm_hz == _ENCODER_INPUT_HZ); in_ptr = in->data; } _enc_buffer_s *out; - A_CALLOC(out, 1); - int size = opus_encode(audio->enc, in_ptr, HZ_TO_FRAMES(ENCODER_INPUT_HZ), out->data, ARRAY_LEN(out->data)); + 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)); free(in); if (size < 0) { - JLOG_PERROR_OPUS(size, "audio", "Fatal: Can't encode PCM frame to OPUS"); + _JLOG_PERROR_OPUS(size, "audio", "Fatal: Can't encode PCM frame to OPUS"); free(out); break; } out->used = size; out->pts = audio->pts; // https://datatracker.ietf.org/doc/html/rfc7587#section-4.2 - audio->pts += HZ_TO_FRAMES(ENCODER_INPUT_HZ); + audio->pts += _HZ_TO_FRAMES(_ENCODER_INPUT_HZ); - if (queue_put(audio->enc_queue, out, 0) != 0) { - JLOG_ERROR("audio", "OPUS encoder queue is full"); + if (us_queue_put(audio->enc_queue, out, 0) != 0) { + US_JLOG_ERROR("audio", "OPUS encoder queue is full"); free(out); } } diff --git a/janus/src/audio.h b/janus/src/audio.h index 753aeec..d8c478d 100644 --- a/janus/src/audio.h +++ b/janus/src/audio.h @@ -51,18 +51,18 @@ typedef struct { SpeexResamplerState *res; OpusEncoder *enc; - queue_s *pcm_queue; - queue_s *enc_queue; + us_queue_s *pcm_queue; + us_queue_s *enc_queue; uint32_t pts; pthread_t pcm_tid; pthread_t enc_tid; bool tids_created; atomic_bool stop; -} audio_s; +} us_audio_s; -audio_s *audio_init(const char *name, unsigned pcm_hz); -void audio_destroy(audio_s *audio); +us_audio_s *us_audio_init(const char *name, unsigned pcm_hz); +void us_audio_destroy(us_audio_s *audio); -int audio_get_encoded(audio_s *audio, uint8_t *data, size_t *size, uint64_t *pts); +int us_audio_get_encoded(us_audio_s *audio, uint8_t *data, size_t *size, uint64_t *pts); diff --git a/janus/src/client.c b/janus/src/client.c index ac686b6..a6b95a9 100644 --- a/janus/src/client.c +++ b/janus/src/client.c @@ -28,53 +28,53 @@ static void *_audio_thread(void *v_client); static void *_common_thread(void *v_client, bool video); -client_s *client_init(janus_callbacks *gw, janus_plugin_session *session, bool has_audio) { - client_s *client; - A_CALLOC(client, 1); +us_janus_client_s *us_janus_client_init(janus_callbacks *gw, janus_plugin_session *session, bool has_audio) { + us_janus_client_s *client; + US_CALLOC(client, 1); client->gw = gw; client->session = session; atomic_init(&client->transmit, true); atomic_init(&client->stop, false); - client->video_queue = queue_init(1024); - A_THREAD_CREATE(&client->video_tid, _video_thread, client); + client->video_queue = us_queue_init(1024); + US_THREAD_CREATE(&client->video_tid, _video_thread, client); if (has_audio) { - client->audio_queue = queue_init(64); - A_THREAD_CREATE(&client->audio_tid, _audio_thread, client); + client->audio_queue = us_queue_init(64); + US_THREAD_CREATE(&client->audio_tid, _audio_thread, client); } return client; } -void client_destroy(client_s *client) { +void us_janus_client_destroy(us_janus_client_s *client) { atomic_store(&client->stop, true); - queue_put(client->video_queue, NULL, 0); + us_queue_put(client->video_queue, NULL, 0); if (client->audio_queue != NULL) { - queue_put(client->audio_queue, NULL, 0); + us_queue_put(client->audio_queue, NULL, 0); } - A_THREAD_JOIN(client->video_tid); - QUEUE_FREE_ITEMS_AND_DESTROY(client->video_queue, rtp_destroy); + US_THREAD_JOIN(client->video_tid); + US_QUEUE_FREE_ITEMS_AND_DESTROY(client->video_queue, us_rtp_destroy); if (client->audio_queue != NULL) { - A_THREAD_JOIN(client->audio_tid); - QUEUE_FREE_ITEMS_AND_DESTROY(client->audio_queue, rtp_destroy); + US_THREAD_JOIN(client->audio_tid); + US_QUEUE_FREE_ITEMS_AND_DESTROY(client->audio_queue, us_rtp_destroy); } free(client); } -void client_send(client_s *client, const rtp_s *rtp) { +void us_janus_client_send(us_janus_client_s *client, const us_rtp_s *rtp) { if ( !atomic_load(&client->transmit) || (!rtp->video && client->audio_queue == NULL) ) { return; } - rtp_s *new = rtp_dup(rtp); - if (queue_put((new->video ? client->video_queue : client->audio_queue), new, 0) != 0) { - JLOG_ERROR("client", "Session %p %s queue is full", + us_rtp_s *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")); - rtp_destroy(new); + us_rtp_destroy(new); } } @@ -87,13 +87,13 @@ static void *_audio_thread(void *v_client) { } static void *_common_thread(void *v_client, bool video) { - client_s *client = (client_s *)v_client; - queue_s *queue = (video ? client->video_queue : client->audio_queue); + us_janus_client_s *client = (us_janus_client_s *)v_client; + us_queue_s *queue = (video ? client->video_queue : client->audio_queue); assert(queue != NULL); // Audio may be NULL while (!atomic_load(&client->stop)) { - rtp_s *rtp; - if (!queue_get(queue, (void **)&rtp, 0.1)) { + us_rtp_s *rtp; + if (!us_queue_get(queue, (void **)&rtp, 0.1)) { if (rtp == NULL) { break; } @@ -112,7 +112,7 @@ static void *_common_thread(void *v_client, bool video) { } client->gw->relay_rtp(client->session, &packet); } - rtp_destroy(rtp); + us_rtp_destroy(rtp); } } return NULL; diff --git a/janus/src/client.h b/janus/src/client.h index c625e5e..5c47993 100644 --- a/janus/src/client.h +++ b/janus/src/client.h @@ -39,7 +39,7 @@ #include "rtp.h" -typedef struct client_sx { +typedef struct us_janus_client_sx { janus_callbacks *gw; janus_plugin_session *session; atomic_bool transmit; @@ -48,14 +48,14 @@ typedef struct client_sx { pthread_t audio_tid; atomic_bool stop; - queue_s *video_queue; - queue_s *audio_queue; + us_queue_s *video_queue; + us_queue_s *audio_queue; - LIST_STRUCT(struct client_sx); -} client_s; + US_LIST_STRUCT(struct us_janus_client_sx); +} us_janus_client_s; -client_s *client_init(janus_callbacks *gw, janus_plugin_session *session, bool has_audio); -void client_destroy(client_s *client); +us_janus_client_s *us_janus_client_init(janus_callbacks *gw, janus_plugin_session *session, bool has_audio); +void us_janus_client_destroy(us_janus_client_s *client); -void client_send(client_s *client, const rtp_s *rtp); +void us_janus_client_send(us_janus_client_s *client, const us_rtp_s *rtp); diff --git a/janus/src/config.c b/janus/src/config.c index 4c6776b..f4a7069 100644 --- a/janus/src/config.c +++ b/janus/src/config.c @@ -27,19 +27,19 @@ static char *_get_value(janus_config *jcfg, const char *section, const char *opt static bool _get_bool(janus_config *jcfg, const char *section, const char *option, bool def); -plugin_config_s *plugin_config_init(const char *config_dir_path) { - plugin_config_s *config; - A_CALLOC(config, 1); +us_config_s *us_config_init(const char *config_dir_path) { + us_config_s *config; + US_CALLOC(config, 1); char *config_file_path; janus_config *jcfg = NULL; - A_ASPRINTF(config_file_path, "%s/%s.jcfg", config_dir_path, PLUGIN_PACKAGE); - JLOG_INFO("config", "Reading config file '%s' ...", config_file_path); + US_ASPRINTF(config_file_path, "%s/%s.jcfg", config_dir_path, US_PLUGIN_PACKAGE); + US_JLOG_INFO("config", "Reading config file '%s' ...", config_file_path); jcfg = janus_config_parse(config_file_path); if (jcfg == NULL) { - JLOG_ERROR("config", "Can't read config"); + US_JLOG_ERROR("config", "Can't read config"); goto error; } janus_config_print(jcfg); @@ -48,23 +48,23 @@ plugin_config_s *plugin_config_init(const char *config_dir_path) { (config->video_sink_name = _get_value(jcfg, "memsink", "object")) == NULL && (config->video_sink_name = _get_value(jcfg, "video", "sink")) == NULL ) { - JLOG_ERROR("config", "Missing config value: video.sink (ex. memsink.object)"); + US_JLOG_ERROR("config", "Missing config value: video.sink (ex. memsink.object)"); goto error; } if ((config->video_zero_playout_delay = _get_bool(jcfg, "video", "zero_playout_delay", false)) == true) { - JLOG_INFO("config", "Enabled the experimental Playout-Delay=0 RTP extension for VIDEO"); + US_JLOG_INFO("config", "Enabled the experimental Playout-Delay=0 RTP extension for VIDEO"); } if ((config->audio_dev_name = _get_value(jcfg, "audio", "device")) != NULL) { - JLOG_INFO("config", "Enabled the experimental AUDIO feature"); + US_JLOG_INFO("config", "Enabled the experimental AUDIO feature"); if ((config->tc358743_dev_path = _get_value(jcfg, "audio", "tc358743")) == NULL) { - JLOG_INFO("config", "Missing config value: audio.tc358743"); + US_JLOG_INFO("config", "Missing config value: audio.tc358743"); goto error; } } goto ok; error: - plugin_config_destroy(config); + us_config_destroy(config); config = NULL; ok: if (jcfg) { @@ -74,10 +74,10 @@ plugin_config_s *plugin_config_init(const char *config_dir_path) { return config; } -void plugin_config_destroy(plugin_config_s *config) { - DELETE(config->video_sink_name, free); - DELETE(config->audio_dev_name, free); - DELETE(config->tc358743_dev_path, free); +void us_config_destroy(us_config_s *config) { + US_DELETE(config->video_sink_name, free); + US_DELETE(config->audio_dev_name, free); + US_DELETE(config->tc358743_dev_path, free); free(config); } diff --git a/janus/src/config.h b/janus/src/config.h index 9f9fe5c..52de3d1 100644 --- a/janus/src/config.h +++ b/janus/src/config.h @@ -40,9 +40,8 @@ typedef struct { char *audio_dev_name; char *tc358743_dev_path; -} plugin_config_s; +} us_config_s; -// config_init() conflicts with something -plugin_config_s *plugin_config_init(const char *config_dir_path); -void plugin_config_destroy(plugin_config_s *config); +us_config_s *us_config_init(const char *config_dir_path); +void us_config_destroy(us_config_s *config); diff --git a/janus/src/const.h b/janus/src/const.h index 337b810..b8b7967 100644 --- a/janus/src/const.h +++ b/janus/src/const.h @@ -22,5 +22,5 @@ #pragma once -#define PLUGIN_NAME "ustreamer" -#define PLUGIN_PACKAGE "janus.plugin.ustreamer" +#define US_PLUGIN_NAME "ustreamer" +#define US_PLUGIN_PACKAGE "janus.plugin.ustreamer" diff --git a/janus/src/logging.h b/janus/src/logging.h index e238f7e..6f30181 100644 --- a/janus/src/logging.h +++ b/janus/src/logging.h @@ -27,12 +27,12 @@ #include "const.h" -#define JLOG_INFO(_prefix, _msg, ...) JANUS_LOG(LOG_INFO, "== %s/%-9s -- " _msg "\n", PLUGIN_NAME, _prefix, ##__VA_ARGS__) -#define JLOG_WARN(_prefix, _msg, ...) JANUS_LOG(LOG_WARN, "== %s/%-9s -- " _msg "\n", PLUGIN_NAME, _prefix, ##__VA_ARGS__) -#define JLOG_ERROR(_prefix, _msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " _msg "\n", PLUGIN_NAME, _prefix, ##__VA_ARGS__) +#define US_JLOG_INFO(x_prefix, x_msg, ...) JANUS_LOG(LOG_INFO, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__) +#define US_JLOG_WARN(x_prefix, x_msg, ...) JANUS_LOG(LOG_WARN, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__) +#define US_JLOG_ERROR(x_prefix, x_msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__) -#define JLOG_PERROR(_prefix, _msg, ...) { \ - char _perror_buf[1024] = {0}; \ - char *_perror_ptr = errno_to_string(errno, _perror_buf, 1023); \ - JANUS_LOG(LOG_ERR, "[%s/%-9s] " _msg ": %s\n", PLUGIN_NAME, _prefix, ##__VA_ARGS__, _perror_ptr); \ +#define US_JLOG_PERROR(x_prefix, x_msg, ...) { \ + char m_perror_buf[1024] = {0}; \ + char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \ + JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_ptr); \ } diff --git a/janus/src/memsinkfd.c b/janus/src/memsinkfd.c index 7041c13..3091e3d 100644 --- a/janus/src/memsinkfd.c +++ b/janus/src/memsinkfd.c @@ -23,21 +23,21 @@ #include "memsinkfd.h" -int memsink_fd_wait_frame(int fd, memsink_shared_s* mem, uint64_t last_id) { - long double deadline_ts = get_now_monotonic() + 1; // wait_timeout +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 long double now; do { - int result = flock_timedwait_monotonic(fd, 1); // lock_timeout - now = get_now_monotonic(); + int result = us_flock_timedwait_monotonic(fd, 1); // lock_timeout + now = us_get_now_monotonic(); if (result < 0 && errno != EWOULDBLOCK) { - JLOG_PERROR("video", "Can't lock memsink"); + US_JLOG_PERROR("video", "Can't lock memsink"); return -1; } else if (result == 0) { - if (mem->magic == MEMSINK_MAGIC && mem->version == MEMSINK_VERSION && mem->id != last_id) { + if (mem->magic == US_MEMSINK_MAGIC && mem->version == US_MEMSINK_VERSION && mem->id != last_id) { return 0; } if (flock(fd, LOCK_UN) < 0) { - JLOG_PERROR("video", "Can't unlock memsink"); + US_JLOG_PERROR("video", "Can't unlock memsink"); return -1; } } @@ -46,24 +46,24 @@ int memsink_fd_wait_frame(int fd, memsink_shared_s* mem, uint64_t last_id) { return -2; } -frame_s *memsink_fd_get_frame(int fd, memsink_shared_s *mem, uint64_t *frame_id) { - frame_s *frame = frame_init(); - frame_set_data(frame, mem->data, mem->used); - FRAME_COPY_META(mem, frame); +us_frame_s *us_memsink_fd_get_frame(int fd, us_memsink_shared_s *mem, uint64_t *frame_id) { + us_frame_s *frame = us_frame_init(); + us_frame_set_data(frame, mem->data, mem->used); + US_FRAME_COPY_META(mem, frame); *frame_id = mem->id; - mem->last_client_ts = get_now_monotonic(); + mem->last_client_ts = us_get_now_monotonic(); bool ok = true; if (frame->format != V4L2_PIX_FMT_H264) { - JLOG_ERROR("video", "Got non-H264 frame from memsink"); + US_JLOG_ERROR("video", "Got non-H264 frame from memsink"); ok = false; } if (flock(fd, LOCK_UN) < 0) { - JLOG_PERROR("video", "Can't unlock memsink"); + US_JLOG_PERROR("video", "Can't unlock memsink"); ok = false; } if (!ok) { - frame_destroy(frame); + us_frame_destroy(frame); frame = NULL; } return frame; diff --git a/janus/src/memsinkfd.h b/janus/src/memsinkfd.h index ee2804c..0414abc 100644 --- a/janus/src/memsinkfd.h +++ b/janus/src/memsinkfd.h @@ -34,5 +34,5 @@ #include "logging.h" -int memsink_fd_wait_frame(int fd, memsink_shared_s* mem, uint64_t last_id); -frame_s *memsink_fd_get_frame(int fd, memsink_shared_s *mem, uint64_t *frame_id); +int us_memsink_fd_wait_frame(int fd, us_memsink_shared_s* mem, uint64_t last_id); +us_frame_s *us_memsink_fd_get_frame(int fd, us_memsink_shared_s *mem, uint64_t *frame_id); diff --git a/janus/src/plugin.c b/janus/src/plugin.c index da125f9..09da27b 100644 --- a/janus/src/plugin.c +++ b/janus/src/plugin.c @@ -55,14 +55,14 @@ #include "config.h" -static plugin_config_s *_g_config = NULL; -const useconds_t _g_watchers_polling = 100000; +static us_config_s *_g_config = NULL; +const useconds_t _g_watchers_polling = 100000; -static client_s *_g_clients = NULL; -static janus_callbacks *_g_gw = NULL; -static queue_s *_g_video_queue = NULL; -static rtpv_s *_g_rtpv = NULL; -static rtpa_s *_g_rtpa = NULL; +static us_janus_client_s *_g_clients = NULL; +static janus_callbacks *_g_gw = NULL; +static us_queue_s *_g_video_queue = NULL; +static us_rtpv_s *_g_rtpv = NULL; +static us_rtpa_s *_g_rtpa = NULL; static pthread_t _g_video_rtp_tid; static atomic_bool _g_video_rtp_tid_created = false; @@ -78,84 +78,84 @@ static atomic_bool _g_stop = false; static atomic_bool _g_has_watchers = false; -#define LOCK_VIDEO A_MUTEX_LOCK(&_g_video_lock) -#define UNLOCK_VIDEO A_MUTEX_UNLOCK(&_g_video_lock) +#define _LOCK_VIDEO US_MUTEX_LOCK(&_g_video_lock) +#define _UNLOCK_VIDEO US_MUTEX_UNLOCK(&_g_video_lock) -#define LOCK_AUDIO A_MUTEX_LOCK(&_g_audio_lock) -#define UNLOCK_AUDIO A_MUTEX_UNLOCK(&_g_audio_lock) +#define _LOCK_AUDIO US_MUTEX_LOCK(&_g_audio_lock) +#define _UNLOCK_AUDIO US_MUTEX_UNLOCK(&_g_audio_lock) -#define LOCK_ALL { LOCK_VIDEO; LOCK_AUDIO; } -#define UNLOCK_ALL { UNLOCK_AUDIO; UNLOCK_VIDEO; } +#define _LOCK_ALL { _LOCK_VIDEO; _LOCK_AUDIO; } +#define _UNLOCK_ALL { _UNLOCK_AUDIO; _UNLOCK_VIDEO; } -#define READY atomic_load(&_g_ready) -#define STOP atomic_load(&_g_stop) -#define HAS_WATCHERS atomic_load(&_g_has_watchers) +#define _READY atomic_load(&_g_ready) +#define _STOP atomic_load(&_g_stop) +#define _HAS_WATCHERS atomic_load(&_g_has_watchers) janus_plugin *create(void); -#define IF_NOT_REPORTED(...) { \ +#define _IF_NOT_REPORTED(...) { \ unsigned _error_code = __LINE__; \ if (error_reported != _error_code) { __VA_ARGS__; error_reported = _error_code; } \ } static void *_video_rtp_thread(UNUSED void *arg) { - A_THREAD_RENAME("us_video_rtp"); + US_THREAD_RENAME("us_video_rtp"); atomic_store(&_g_video_rtp_tid_created, true); - while (!STOP) { - frame_s *frame; - if (queue_get(_g_video_queue, (void **)&frame, 0.1) == 0) { - LOCK_VIDEO; - rtpv_wrap(_g_rtpv, frame); - UNLOCK_VIDEO; - frame_destroy(frame); + while (!_STOP) { + us_frame_s *frame; + if (us_queue_get(_g_video_queue, (void **)&frame, 0.1) == 0) { + _LOCK_VIDEO; + us_rtpv_wrap(_g_rtpv, frame); + _UNLOCK_VIDEO; + us_frame_destroy(frame); } } return NULL; } static void *_video_sink_thread(UNUSED void *arg) { - A_THREAD_RENAME("us_video_sink"); + US_THREAD_RENAME("us_video_sink"); atomic_store(&_g_video_sink_tid_created, true); uint64_t frame_id = 0; unsigned error_reported = 0; - while (!STOP) { - if (!HAS_WATCHERS) { - IF_NOT_REPORTED({ JLOG_INFO("video", "No active watchers, memsink disconnected"); }); + while (!_STOP) { + if (!_HAS_WATCHERS) { + _IF_NOT_REPORTED({ US_JLOG_INFO("video", "No active watchers, memsink disconnected"); }); usleep(_g_watchers_polling); continue; } int fd = -1; - memsink_shared_s *mem = NULL; + us_memsink_shared_s *mem = NULL; if ((fd = shm_open(_g_config->video_sink_name, O_RDWR, 0)) <= 0) { - IF_NOT_REPORTED({ JLOG_PERROR("video", "Can't open memsink"); }); + _IF_NOT_REPORTED({ US_JLOG_PERROR("video", "Can't open memsink"); }); goto close_memsink; } - if ((mem = memsink_shared_map(fd)) == NULL) { - IF_NOT_REPORTED({ JLOG_PERROR("video", "Can't map memsink"); }); + if ((mem = us_memsink_shared_map(fd)) == NULL) { + _IF_NOT_REPORTED({ US_JLOG_PERROR("video", "Can't map memsink"); }); goto close_memsink; } error_reported = 0; - JLOG_INFO("video", "Memsink opened; reading frames ..."); - while (!STOP && HAS_WATCHERS) { - int result = memsink_fd_wait_frame(fd, mem, frame_id); + US_JLOG_INFO("video", "Memsink opened; reading frames ..."); + while (!_STOP && _HAS_WATCHERS) { + int result = us_memsink_fd_wait_frame(fd, mem, frame_id); if (result == 0) { - frame_s *frame = memsink_fd_get_frame(fd, mem, &frame_id); + us_frame_s *frame = us_memsink_fd_get_frame(fd, mem, &frame_id); if (frame == NULL) { goto close_memsink; } - if (queue_put(_g_video_queue, frame, 0) != 0) { - IF_NOT_REPORTED({ JLOG_PERROR("video", "Video queue is full"); }); - frame_destroy(frame); + if (us_queue_put(_g_video_queue, frame, 0) != 0) { + _IF_NOT_REPORTED({ US_JLOG_PERROR("video", "Video queue is full"); }); + us_frame_destroy(frame); } } else if (result == -1) { goto close_memsink; @@ -164,8 +164,8 @@ static void *_video_sink_thread(UNUSED void *arg) { close_memsink: if (mem != NULL) { - JLOG_INFO("video", "Memsink closed"); - memsink_shared_unmap(mem); + US_JLOG_INFO("video", "Memsink closed"); + us_memsink_shared_unmap(mem); mem = NULL; } if (fd > 0) { @@ -178,53 +178,53 @@ static void *_video_sink_thread(UNUSED void *arg) { } static void *_audio_thread(UNUSED void *arg) { - A_THREAD_RENAME("us_audio"); + US_THREAD_RENAME("us_audio"); atomic_store(&_g_audio_tid_created, true); assert(_g_config->audio_dev_name); assert(_g_config->tc358743_dev_path); unsigned error_reported = 0; - while (!STOP) { - if (!HAS_WATCHERS) { + while (!_STOP) { + if (!_HAS_WATCHERS) { usleep(_g_watchers_polling); continue; } - tc358743_info_s info = {0}; - audio_s *audio = NULL; + us_tc358743_info_s info = {0}; + us_audio_s *audio = NULL; - if (tc358743_read_info(_g_config->tc358743_dev_path, &info) < 0) { + if (us_tc358743_read_info(_g_config->tc358743_dev_path, &info) < 0) { goto close_audio; } if (!info.has_audio) { - IF_NOT_REPORTED({ JLOG_INFO("audio", "No audio presented from the host"); }); + _IF_NOT_REPORTED({ US_JLOG_INFO("audio", "No audio presented from the host"); }); goto close_audio; } - IF_NOT_REPORTED({ JLOG_INFO("audio", "Detected host audio"); }); - if ((audio = audio_init(_g_config->audio_dev_name, info.audio_hz)) == NULL) { + _IF_NOT_REPORTED({ US_JLOG_INFO("audio", "Detected host audio"); }); + if ((audio = us_audio_init(_g_config->audio_dev_name, info.audio_hz)) == NULL) { goto close_audio; } error_reported = 0; - while (!STOP && HAS_WATCHERS) { + while (!_STOP && _HAS_WATCHERS) { if ( - tc358743_read_info(_g_config->tc358743_dev_path, &info) < 0 + us_tc358743_read_info(_g_config->tc358743_dev_path, &info) < 0 || !info.has_audio || audio->pcm_hz != info.audio_hz ) { goto close_audio; } - size_t size = RTP_DATAGRAM_SIZE - RTP_HEADER_SIZE; + size_t size = US_RTP_DATAGRAM_SIZE - US_RTP_HEADER_SIZE; uint8_t data[size]; uint64_t pts; - int result = audio_get_encoded(audio, data, &size, &pts); + int result = us_audio_get_encoded(audio, data, &size, &pts); if (result == 0) { - LOCK_AUDIO; - rtpa_wrap(_g_rtpa, data, size, pts); - UNLOCK_AUDIO; + _LOCK_AUDIO; + us_rtpa_wrap(_g_rtpa, data, size, pts); + _UNLOCK_AUDIO; } else if (result == -1) { goto close_audio; } @@ -232,18 +232,18 @@ static void *_audio_thread(UNUSED void *arg) { close_audio: if (audio != NULL) { - audio_destroy(audio); + us_audio_destroy(audio); } sleep(1); // error_delay } return NULL; } -#undef IF_NOT_REPORTED +#undef _IF_NOT_REPORTED -static void _relay_rtp_clients(const rtp_s *rtp) { - LIST_ITERATE(_g_clients, client, { - client_send(client, rtp); +static void _relay_rtp_clients(const us_rtp_s *rtp) { + US_LIST_ITERATE(_g_clients, client, { + us_janus_client_send(client, rtp); }); } @@ -254,117 +254,117 @@ static int _plugin_init(janus_callbacks *gw, const char *config_dir_path) { // sysctl -w net.core.rmem_max=1000000 // sysctl -w net.core.wmem_max=1000000 - JLOG_INFO("main", "Initializing plugin ..."); - if (gw == NULL || config_dir_path == NULL || ((_g_config = plugin_config_init(config_dir_path)) == NULL)) { + US_JLOG_INFO("main", "Initializing plugin ..."); + if (gw == NULL || config_dir_path == NULL || ((_g_config = us_config_init(config_dir_path)) == NULL)) { return -1; } _g_gw = gw; - _g_video_queue = queue_init(1024); - _g_rtpv = rtpv_init(_relay_rtp_clients, _g_config->video_zero_playout_delay); + _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) { - _g_rtpa = rtpa_init(_relay_rtp_clients); - A_THREAD_CREATE(&_g_audio_tid, _audio_thread, NULL); + _g_rtpa = us_rtpa_init(_relay_rtp_clients); + US_THREAD_CREATE(&_g_audio_tid, _audio_thread, NULL); } - A_THREAD_CREATE(&_g_video_rtp_tid, _video_rtp_thread, NULL); - A_THREAD_CREATE(&_g_video_sink_tid, _video_sink_thread, NULL); + US_THREAD_CREATE(&_g_video_rtp_tid, _video_rtp_thread, NULL); + US_THREAD_CREATE(&_g_video_sink_tid, _video_sink_thread, NULL); atomic_store(&_g_ready, true); return 0; } static void _plugin_destroy(void) { - JLOG_INFO("main", "Destroying plugin ..."); + US_JLOG_INFO("main", "Destroying plugin ..."); atomic_store(&_g_stop, true); -# define JOIN(_tid) { if (atomic_load(&_tid##_created)) { A_THREAD_JOIN(_tid); } } +# define JOIN(_tid) { if (atomic_load(&_tid##_created)) { US_THREAD_JOIN(_tid); } } JOIN(_g_video_sink_tid); JOIN(_g_video_rtp_tid); JOIN(_g_audio_tid); # undef JOIN - LIST_ITERATE(_g_clients, client, { - LIST_REMOVE(_g_clients, client); - client_destroy(client); + US_LIST_ITERATE(_g_clients, client, { + US_LIST_REMOVE(_g_clients, client); + us_janus_client_destroy(client); }); - QUEUE_FREE_ITEMS_AND_DESTROY(_g_video_queue, frame_destroy); + US_QUEUE_FREE_ITEMS_AND_DESTROY(_g_video_queue, us_frame_destroy); - DELETE(_g_rtpa, rtpa_destroy); - DELETE(_g_rtpv, rtpv_destroy); - DELETE(_g_config, plugin_config_destroy); + US_DELETE(_g_rtpa, us_rtpa_destroy); + US_DELETE(_g_rtpv, us_rtpv_destroy); + US_DELETE(_g_config, us_config_destroy); } -#define IF_DISABLED(...) { if (!READY || STOP) { __VA_ARGS__ } } +#define _IF_DISABLED(...) { if (!_READY || _STOP) { __VA_ARGS__ } } static void _plugin_create_session(janus_plugin_session *session, int *err) { - IF_DISABLED({ *err = -1; return; }); - LOCK_ALL; - JLOG_INFO("main", "Creating session %p ...", session); - client_s *client = client_init(_g_gw, session, (_g_config->audio_dev_name != NULL)); - LIST_APPEND(_g_clients, client); + _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_LIST_APPEND(_g_clients, client); atomic_store(&_g_has_watchers, true); - UNLOCK_ALL; + _UNLOCK_ALL; } static void _plugin_destroy_session(janus_plugin_session* session, int *err) { - IF_DISABLED({ *err = -1; return; }); - LOCK_ALL; + _IF_DISABLED({ *err = -1; return; }); + _LOCK_ALL; bool found = false; bool has_watchers = false; - LIST_ITERATE(_g_clients, client, { + US_LIST_ITERATE(_g_clients, client, { if (client->session == session) { - JLOG_INFO("main", "Removing session %p ...", session); - LIST_REMOVE(_g_clients, client); - client_destroy(client); + US_JLOG_INFO("main", "Removing session %p ...", session); + US_LIST_REMOVE(_g_clients, client); + us_janus_client_destroy(client); found = true; } else { has_watchers = (has_watchers || atomic_load(&client->transmit)); } }); if (!found) { - JLOG_WARN("main", "No session %p", session); + US_JLOG_WARN("main", "No session %p", session); *err = -2; } atomic_store(&_g_has_watchers, has_watchers); - UNLOCK_ALL; + _UNLOCK_ALL; } static json_t *_plugin_query_session(janus_plugin_session *session) { - IF_DISABLED({ return NULL; }); + _IF_DISABLED({ return NULL; }); json_t *info = NULL; - LOCK_ALL; - LIST_ITERATE(_g_clients, client, { + _LOCK_ALL; + US_LIST_ITERATE(_g_clients, client, { if (client->session == session) { info = json_string("session_found"); break; } }); - UNLOCK_ALL; + _UNLOCK_ALL; return info; } static void _set_transmit(janus_plugin_session *session, UNUSED const char *msg, bool transmit) { - IF_DISABLED({ return; }); - LOCK_ALL; + _IF_DISABLED({ return; }); + _LOCK_ALL; bool found = false; bool has_watchers = false; - LIST_ITERATE(_g_clients, client, { + US_LIST_ITERATE(_g_clients, client, { if (client->session == session) { atomic_store(&client->transmit, transmit); - // JLOG_INFO("main", "%s session %p", msg, session); + // US_JLOG_INFO("main", "%s session %p", msg, session); found = true; } has_watchers = (has_watchers || atomic_load(&client->transmit)); }); if (!found) { - JLOG_WARN("main", "No session %p", session); + US_JLOG_WARN("main", "No session %p", session); } atomic_store(&_g_has_watchers, has_watchers); - UNLOCK_ALL; + _UNLOCK_ALL; } -#undef IF_DISABLED +#undef _IF_DISABLED static void _plugin_setup_media(janus_plugin_session *session) { _set_transmit(session, "Unmuted", true); } static void _plugin_hangup_media(janus_plugin_session *session) { _set_transmit(session, "Muted", false); } @@ -385,14 +385,14 @@ static struct janus_plugin_result *_plugin_handle_message( return janus_plugin_result_new(JANUS_PLUGIN_ERROR, (msg ? "No session" : "No message"), NULL); } -# define PUSH_ERROR(_error, _reason) { \ - /*JLOG_ERROR("main", "Message error in session %p: %s", session, _reason);*/ \ - json_t *_event = json_object(); \ - json_object_set_new(_event, "ustreamer", json_string("event")); \ - json_object_set_new(_event, "error_code", json_integer(_error)); \ - json_object_set_new(_event, "error", json_string(_reason)); \ - _g_gw->push_event(session, create(), transaction, _event, NULL); \ - json_decref(_event); \ +# define PUSH_ERROR(x_error, x_reason) { \ + /*US_JLOG_ERROR("main", "Message error in session %p: %s", session, x_reason);*/ \ + json_t *m_event = json_object(); \ + json_object_set_new(m_event, "ustreamer", json_string("event")); \ + json_object_set_new(m_event, "error_code", json_integer(x_error)); \ + json_object_set_new(m_event, "error", json_string(x_reason)); \ + _g_gw->push_event(session, create(), transaction, m_event, NULL); \ + json_decref(m_event); \ } json_t *request_obj = json_object_get(msg, "request"); @@ -406,16 +406,16 @@ static struct janus_plugin_result *_plugin_handle_message( PUSH_ERROR(400, "Request not a string"); goto ok_wait; } - // JLOG_INFO("main", "Message: %s", request_str); + // US_JLOG_INFO("main", "Message: %s", request_str); -# define PUSH_STATUS(_status, _jsep) { \ - json_t *_event = json_object(); \ - json_object_set_new(_event, "ustreamer", json_string("event")); \ - json_t *_result = json_object(); \ - json_object_set_new(_result, "status", json_string(_status)); \ - json_object_set_new(_event, "result", _result); \ - _g_gw->push_event(session, create(), transaction, _event, _jsep); \ - json_decref(_event); \ +# define PUSH_STATUS(x_status, x_jsep) { \ + json_t *m_event = json_object(); \ + json_object_set_new(m_event, "ustreamer", json_string("event")); \ + json_t *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); \ + json_decref(m_event); \ } if (!strcmp(request_str, "start")) { @@ -427,19 +427,19 @@ static struct janus_plugin_result *_plugin_handle_message( } else if (!strcmp(request_str, "watch")) { char *sdp; { - char *video_sdp = rtpv_make_sdp(_g_rtpv); + char *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 ? rtpa_make_sdp(_g_rtpa) : strdup("")); - A_ASPRINTF(sdp, + char *audio_sdp = (_g_rtpa ? us_rtpa_make_sdp(_g_rtpa) : strdup("")); + US_ASPRINTF(sdp, "v=0" RN "o=- %" PRIu64 " 1 IN IP4 0.0.0.0" RN "s=PiKVM uStreamer" RN "t=0 0" RN "%s%s", - get_now_id() >> 1, audio_sdp, video_sdp + us_get_now_id() >> 1, audio_sdp, video_sdp ); free(audio_sdp); free(video_sdp); @@ -466,12 +466,12 @@ static struct janus_plugin_result *_plugin_handle_message( // ***** Plugin ***** static int _plugin_get_api_compatibility(void) { return JANUS_PLUGIN_API_VERSION; } -static int _plugin_get_version(void) { return VERSION_U; } -static const char *_plugin_get_version_string(void) { return VERSION; } +static int _plugin_get_version(void) { return US_VERSION_U; } +static const char *_plugin_get_version_string(void) { return US_VERSION; } static const char *_plugin_get_description(void) { return "PiKVM uStreamer Janus plugin for H.264 video"; } -static const char *_plugin_get_name(void) { return PLUGIN_NAME; } +static const char *_plugin_get_name(void) { return US_PLUGIN_NAME; } static const char *_plugin_get_author(void) { return "Maxim Devaev "; } -static const char *_plugin_get_package(void) { return PLUGIN_PACKAGE; } +static const char *_plugin_get_package(void) { return US_PLUGIN_PACKAGE; } static void _plugin_incoming_rtp(UNUSED janus_plugin_session *handle, UNUSED janus_plugin_rtp *packet) { // Just a stub to avoid logging spam about the plugin's purpose diff --git a/janus/src/queue.c b/janus/src/queue.c index cf32e4e..0803f07 100644 --- a/janus/src/queue.c +++ b/janus/src/queue.c @@ -23,12 +23,12 @@ #include "queue.h" -queue_s *queue_init(unsigned capacity) { - queue_s *queue; - A_CALLOC(queue, 1); - A_CALLOC(queue->items, capacity); +us_queue_s *us_queue_init(unsigned capacity) { + us_queue_s *queue; + US_CALLOC(queue, 1); + US_CALLOC(queue->items, capacity); queue->capacity = capacity; - A_MUTEX_INIT(&queue->mutex); + US_MUTEX_INIT(&queue->mutex); pthread_condattr_t attrs; assert(!pthread_condattr_init(&attrs)); @@ -39,61 +39,61 @@ queue_s *queue_init(unsigned capacity) { return queue; } -void queue_destroy(queue_s *queue) { +void us_queue_destroy(us_queue_s *queue) { free(queue->items); free(queue); } -#define WAIT_OR_UNLOCK(_var, _cond) { \ - struct timespec _ts; \ - assert(!clock_gettime(CLOCK_MONOTONIC, &_ts)); \ - ld_to_timespec(timespec_to_ld(&_ts) + timeout, &_ts); \ - while (_var) { \ - int err = pthread_cond_timedwait(_cond, &queue->mutex, &_ts); \ +#define _WAIT_OR_UNLOCK(x_var, x_cond) { \ + struct timespec m_ts; \ + 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); \ if (err == ETIMEDOUT) { \ - A_MUTEX_UNLOCK(&queue->mutex); \ + US_MUTEX_UNLOCK(&queue->mutex); \ return -1; \ } \ assert(!err); \ } \ } -int queue_put(queue_s *queue, void *item, long double timeout) { - A_MUTEX_LOCK(&queue->mutex); +int us_queue_put(us_queue_s *queue, void *item, long double timeout) { + US_MUTEX_LOCK(&queue->mutex); if (timeout == 0) { if (queue->size == queue->capacity) { - A_MUTEX_UNLOCK(&queue->mutex); + US_MUTEX_UNLOCK(&queue->mutex); return -1; } } else { - WAIT_OR_UNLOCK(queue->size == queue->capacity, &queue->full_cond); + _WAIT_OR_UNLOCK(queue->size == queue->capacity, &queue->full_cond); } queue->items[queue->in] = item; ++queue->size; ++queue->in; queue->in %= queue->capacity; - A_MUTEX_UNLOCK(&queue->mutex); + US_MUTEX_UNLOCK(&queue->mutex); assert(!pthread_cond_broadcast(&queue->empty_cond)); return 0; } -int queue_get(queue_s *queue, void **item, long double timeout) { - A_MUTEX_LOCK(&queue->mutex); - WAIT_OR_UNLOCK(queue->size == 0, &queue->empty_cond); +int us_queue_get(us_queue_s *queue, void **item, long double timeout) { + US_MUTEX_LOCK(&queue->mutex); + _WAIT_OR_UNLOCK(queue->size == 0, &queue->empty_cond); *item = queue->items[queue->out]; --queue->size; ++queue->out; queue->out %= queue->capacity; - A_MUTEX_UNLOCK(&queue->mutex); + US_MUTEX_UNLOCK(&queue->mutex); assert(!pthread_cond_broadcast(&queue->full_cond)); return 0; } -#undef WAIT_OR_UNLOCK +#undef _WAIT_OR_UNLOCK -int queue_get_free(queue_s *queue) { - A_MUTEX_LOCK(&queue->mutex); +int us_queue_get_free(us_queue_s *queue) { + US_MUTEX_LOCK(&queue->mutex); unsigned size = queue->size; - A_MUTEX_UNLOCK(&queue->mutex); + US_MUTEX_UNLOCK(&queue->mutex); return queue->capacity - size; } diff --git a/janus/src/queue.h b/janus/src/queue.h index b31107b..bd95735 100644 --- a/janus/src/queue.h +++ b/janus/src/queue.h @@ -44,26 +44,26 @@ typedef struct { pthread_mutex_t mutex; pthread_cond_t full_cond; pthread_cond_t empty_cond; -} queue_s; +} us_queue_s; -#define QUEUE_FREE_ITEMS_AND_DESTROY(_queue, _free_item) { \ - if (_queue) { \ - while (!queue_get_free(_queue)) { \ - void *_ptr; \ - assert(!queue_get(_queue, &_ptr, 0.1)); \ - if (_ptr != NULL) { \ - _free_item(_ptr); \ +#define US_QUEUE_FREE_ITEMS_AND_DESTROY(x_queue, x_free_item) { \ + if (x_queue) { \ + while (!us_queue_get_free(x_queue)) { \ + void *m_ptr; \ + assert(!us_queue_get(x_queue, &m_ptr, 0.1)); \ + if (m_ptr != NULL) { \ + x_free_item(m_ptr); \ } \ } \ - queue_destroy(_queue); \ + us_queue_destroy(x_queue); \ } \ } -queue_s *queue_init(unsigned capacity); -void queue_destroy(queue_s *queue); +us_queue_s *us_queue_init(unsigned capacity); +void us_queue_destroy(us_queue_s *queue); -int queue_put(queue_s *queue, void *item, long double timeout); -int queue_get(queue_s *queue, void **item, long double timeout); -int queue_get_free(queue_s *queue); +int us_queue_put(us_queue_s *queue, void *item, long double timeout); +int us_queue_get(us_queue_s *queue, void **item, long double timeout); +int us_queue_get_free(us_queue_s *queue); diff --git a/janus/src/rtp.c b/janus/src/rtp.c index cc11f60..b7f0ea9 100644 --- a/janus/src/rtp.c +++ b/janus/src/rtp.c @@ -26,28 +26,28 @@ #include "rtp.h" -rtp_s *rtp_init(unsigned payload, bool video, bool zero_playout_delay) { - rtp_s *rtp; - A_CALLOC(rtp, 1); +us_rtp_s *us_rtp_init(unsigned payload, bool video, bool zero_playout_delay) { + us_rtp_s *rtp; + US_CALLOC(rtp, 1); rtp->payload = payload; rtp->video = video; rtp->zero_playout_delay = zero_playout_delay; // See client.c - rtp->ssrc = triple_u32(get_now_monotonic_u64()); + rtp->ssrc = us_triple_u32(us_get_now_monotonic_u64()); return rtp; } -rtp_s *rtp_dup(const rtp_s *rtp) { - rtp_s *new; - A_CALLOC(new, 1); - memcpy(new, rtp, sizeof(rtp_s)); +us_rtp_s *us_rtp_dup(const us_rtp_s *rtp) { + us_rtp_s *new; + US_CALLOC(new, 1); + memcpy(new, rtp, sizeof(us_rtp_s)); return new; } -void rtp_destroy(rtp_s *rtp) { +void us_rtp_destroy(us_rtp_s *rtp) { free(rtp); } -void rtp_write_header(rtp_s *rtp, uint32_t pts, bool marked) { +void us_rtp_write_header(us_rtp_s *rtp, uint32_t pts, bool marked) { uint32_t word0 = 0x80000000; if (marked) { word0 |= 1 << 23; diff --git a/janus/src/rtp.h b/janus/src/rtp.h index 45a6d63..372bbbe 100644 --- a/janus/src/rtp.h +++ b/janus/src/rtp.h @@ -32,8 +32,8 @@ // https://stackoverflow.com/questions/47635545/why-webrtc-chose-rtp-max-packet-size-to-1200-bytes -#define RTP_DATAGRAM_SIZE 1200 -#define RTP_HEADER_SIZE 12 +#define US_RTP_DATAGRAM_SIZE 1200 +#define US_RTP_HEADER_SIZE 12 typedef struct { @@ -43,15 +43,15 @@ typedef struct { uint32_t ssrc; uint16_t seq; - uint8_t datagram[RTP_DATAGRAM_SIZE]; + uint8_t datagram[US_RTP_DATAGRAM_SIZE]; size_t used; -} rtp_s; +} us_rtp_s; -typedef void (*rtp_callback_f)(const rtp_s *rtp); +typedef void (*us_rtp_callback_f)(const us_rtp_s *rtp); -rtp_s *rtp_init(unsigned payload, bool video, bool zero_playout_delay); -rtp_s *rtp_dup(const rtp_s *rtp); -void rtp_destroy(rtp_s *rtp); +us_rtp_s *us_rtp_init(unsigned payload, bool video, bool zero_playout_delay); +us_rtp_s *us_rtp_dup(const us_rtp_s *rtp); +void us_rtp_destroy(us_rtp_s *rtp); -void rtp_write_header(rtp_s *rtp, uint32_t pts, bool marked); +void us_rtp_write_header(us_rtp_s *rtp, uint32_t pts, bool marked); diff --git a/janus/src/rtpa.c b/janus/src/rtpa.c index 6d18354..8c2305d 100644 --- a/janus/src/rtpa.c +++ b/janus/src/rtpa.c @@ -23,23 +23,23 @@ #include "rtpa.h" -rtpa_s *rtpa_init(rtp_callback_f callback) { - rtpa_s *rtpa; - A_CALLOC(rtpa, 1); - rtpa->rtp = rtp_init(111, false, false); +us_rtpa_s *us_rtpa_init(us_rtp_callback_f callback) { + us_rtpa_s *rtpa; + US_CALLOC(rtpa, 1); + rtpa->rtp = us_rtp_init(111, false, false); rtpa->callback = callback; return rtpa; } -void rtpa_destroy(rtpa_s *rtpa) { - rtp_destroy(rtpa->rtp); +void us_rtpa_destroy(us_rtpa_s *rtpa) { + us_rtp_destroy(rtpa->rtp); free(rtpa); } -char *rtpa_make_sdp(rtpa_s *rtpa) { +char *us_rtpa_make_sdp(us_rtpa_s *rtpa) { # define PAYLOAD rtpa->rtp->payload char *sdp; - A_ASPRINTF(sdp, + US_ASPRINTF(sdp, "m=audio 1 RTP/SAVPF %u" RN "c=IN IP4 0.0.0.0" RN "a=rtpmap:%u OPUS/48000/2" RN @@ -56,11 +56,11 @@ char *rtpa_make_sdp(rtpa_s *rtpa) { return sdp; } -void rtpa_wrap(rtpa_s *rtpa, const uint8_t *data, size_t size, uint32_t pts) { - if (size + RTP_HEADER_SIZE <= RTP_DATAGRAM_SIZE) { - rtp_write_header(rtpa->rtp, pts, false); - memcpy(rtpa->rtp->datagram + RTP_HEADER_SIZE, data, size); - rtpa->rtp->used = size + RTP_HEADER_SIZE; +void us_rtpa_wrap(us_rtpa_s *rtpa, const uint8_t *data, size_t size, uint32_t pts) { + if (size + US_RTP_HEADER_SIZE <= US_RTP_DATAGRAM_SIZE) { + us_rtp_write_header(rtpa->rtp, pts, false); + memcpy(rtpa->rtp->datagram + US_RTP_HEADER_SIZE, data, size); + rtpa->rtp->used = size + US_RTP_HEADER_SIZE; rtpa->callback(rtpa->rtp); } } diff --git a/janus/src/rtpa.h b/janus/src/rtpa.h index 167f4fe..53debfc 100644 --- a/janus/src/rtpa.h +++ b/janus/src/rtpa.h @@ -36,13 +36,13 @@ typedef struct { - rtp_s *rtp; - rtp_callback_f callback; -} rtpa_s; + us_rtp_s *rtp; + us_rtp_callback_f callback; +} us_rtpa_s; -rtpa_s *rtpa_init(rtp_callback_f callback); -void rtpa_destroy(rtpa_s *rtpa); +us_rtpa_s *us_rtpa_init(us_rtp_callback_f callback); +void us_rtpa_destroy(us_rtpa_s *rtpa); -char *rtpa_make_sdp(rtpa_s *rtpa); -void rtpa_wrap(rtpa_s *rtpa, const uint8_t *data, size_t size, uint32_t pts); +char *us_rtpa_make_sdp(us_rtpa_s *rtpa); +void us_rtpa_wrap(us_rtpa_s *rtpa, const uint8_t *data, size_t size, uint32_t pts); diff --git a/janus/src/rtpv.c b/janus/src/rtpv.c index ec86088..6715270 100644 --- a/janus/src/rtpv.c +++ b/janus/src/rtpv.c @@ -26,50 +26,50 @@ #include "rtpv.h" -void _rtpv_process_nalu(rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t pts, bool marked); +void _rtpv_process_nalu(us_rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t pts, bool marked); static ssize_t _find_annexb(const uint8_t *data, size_t size); -rtpv_s *rtpv_init(rtp_callback_f callback, bool zero_playout_delay) { - rtpv_s *rtpv; - A_CALLOC(rtpv, 1); - rtpv->rtp = rtp_init(96, true, zero_playout_delay); +us_rtpv_s *us_rtpv_init(us_rtp_callback_f callback, bool zero_playout_delay) { + us_rtpv_s *rtpv; + US_CALLOC(rtpv, 1); + rtpv->rtp = us_rtp_init(96, true, zero_playout_delay); rtpv->callback = callback; - rtpv->sps = frame_init(); - rtpv->pps = frame_init(); - A_MUTEX_INIT(&rtpv->mutex); + rtpv->sps = us_frame_init(); + rtpv->pps = us_frame_init(); + US_MUTEX_INIT(&rtpv->mutex); return rtpv; } -void rtpv_destroy(rtpv_s *rtpv) { - A_MUTEX_DESTROY(&rtpv->mutex); - frame_destroy(rtpv->pps); - frame_destroy(rtpv->sps); - rtp_destroy(rtpv->rtp); +void us_rtpv_destroy(us_rtpv_s *rtpv) { + US_MUTEX_DESTROY(&rtpv->mutex); + us_frame_destroy(rtpv->pps); + us_frame_destroy(rtpv->sps); + us_rtp_destroy(rtpv->rtp); free(rtpv); } -char *rtpv_make_sdp(rtpv_s *rtpv) { - A_MUTEX_LOCK(&rtpv->mutex); +char *us_rtpv_make_sdp(us_rtpv_s *rtpv) { + US_MUTEX_LOCK(&rtpv->mutex); if (rtpv->sps->used == 0 || rtpv->pps->used == 0) { - A_MUTEX_UNLOCK(&rtpv->mutex); + US_MUTEX_UNLOCK(&rtpv->mutex); return NULL; } char *sps = NULL; char *pps = NULL; - base64_encode(rtpv->sps->data, rtpv->sps->used, &sps, NULL); - base64_encode(rtpv->pps->data, rtpv->pps->used, &pps, NULL); + us_base64_encode(rtpv->sps->data, rtpv->sps->used, &sps, NULL); + us_base64_encode(rtpv->pps->data, rtpv->pps->used, &pps, NULL); - A_MUTEX_UNLOCK(&rtpv->mutex); + US_MUTEX_UNLOCK(&rtpv->mutex); # define PAYLOAD rtpv->rtp->payload // https://tools.ietf.org/html/rfc6184 // https://github.com/meetecho/janus-gateway/issues/2443 char *sdp; - A_ASPRINTF(sdp, + US_ASPRINTF(sdp, "m=video 1 RTP/SAVPF %u" RN "c=IN IP4 0.0.0.0" RN "a=rtpmap:%u H264/90000" RN @@ -97,19 +97,19 @@ char *rtpv_make_sdp(rtpv_s *rtpv) { return sdp; } -#define PRE 3 // Annex B prefix length +#define _PRE 3 // Annex B prefix length -void rtpv_wrap(rtpv_s *rtpv, const frame_s *frame) { +void us_rtpv_wrap(us_rtpv_s *rtpv, const us_frame_s *frame) { // There is a complicated logic here but everything works as it should: // - https://github.com/pikvm/ustreamer/issues/115#issuecomment-893071775 assert(frame->format == V4L2_PIX_FMT_H264); - const uint32_t pts = get_now_monotonic_u64() * 9 / 100; // PTS units are in 90 kHz - ssize_t last_offset = -PRE; + const uint32_t pts = us_get_now_monotonic_u64() * 9 / 100; // PTS units are in 90 kHz + ssize_t last_offset = -_PRE; while (true) { // Find and iterate by nalus - const size_t next_start = last_offset + PRE; + const size_t next_start = last_offset + _PRE; ssize_t offset = _find_annexb(frame->data + next_start, frame->used - next_start); if (offset < 0) { break; @@ -117,8 +117,8 @@ void rtpv_wrap(rtpv_s *rtpv, const frame_s *frame) { offset += next_start; if (last_offset >= 0) { - const uint8_t *data = frame->data + last_offset + PRE; - size_t size = offset - last_offset - PRE; + const uint8_t *data = frame->data + last_offset + _PRE; + size_t size = offset - last_offset - _PRE; if (data[size - 1] == 0) { // Check for extra 00 --size; } @@ -129,53 +129,53 @@ void rtpv_wrap(rtpv_s *rtpv, const frame_s *frame) { } if (last_offset >= 0) { - const uint8_t *data = frame->data + last_offset + PRE; - size_t size = frame->used - last_offset - PRE; + const uint8_t *data = frame->data + last_offset + _PRE; + size_t size = frame->used - last_offset - _PRE; _rtpv_process_nalu(rtpv, data, size, pts, true); } } -void _rtpv_process_nalu(rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t pts, bool marked) { +void _rtpv_process_nalu(us_rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t pts, bool marked) { const unsigned ref_idc = (data[0] >> 5) & 3; const unsigned type = data[0] & 0x1F; - frame_s *ps = NULL; + us_frame_s *ps = NULL; switch (type) { case 7: ps = rtpv->sps; break; case 8: ps = rtpv->pps; break; } if (ps) { - A_MUTEX_LOCK(&rtpv->mutex); - frame_set_data(ps, data, size); - A_MUTEX_UNLOCK(&rtpv->mutex); + US_MUTEX_LOCK(&rtpv->mutex); + us_frame_set_data(ps, data, size); + US_MUTEX_UNLOCK(&rtpv->mutex); } # define DG rtpv->rtp->datagram - if (size + RTP_HEADER_SIZE <= RTP_DATAGRAM_SIZE) { - rtp_write_header(rtpv->rtp, pts, marked); - memcpy(DG + RTP_HEADER_SIZE, data, size); - rtpv->rtp->used = size + RTP_HEADER_SIZE; + if (size + US_RTP_HEADER_SIZE <= US_RTP_DATAGRAM_SIZE) { + us_rtp_write_header(rtpv->rtp, pts, marked); + memcpy(DG + US_RTP_HEADER_SIZE, data, size); + rtpv->rtp->used = size + US_RTP_HEADER_SIZE; rtpv->callback(rtpv->rtp); return; } - const size_t fu_overhead = RTP_HEADER_SIZE + 2; // FU-A overhead + const size_t fu_overhead = US_RTP_HEADER_SIZE + 2; // FU-A overhead const uint8_t *src = data + 1; ssize_t remaining = size - 1; bool first = true; while (remaining > 0) { - ssize_t frag_size = RTP_DATAGRAM_SIZE - fu_overhead; + ssize_t frag_size = US_RTP_DATAGRAM_SIZE - fu_overhead; const bool last = (remaining <= frag_size); if (last) { frag_size = remaining; } - rtp_write_header(rtpv->rtp, pts, (marked && last)); + us_rtp_write_header(rtpv->rtp, pts, (marked && last)); - DG[RTP_HEADER_SIZE] = 28 | (ref_idc << 5); + DG[US_RTP_HEADER_SIZE] = 28 | (ref_idc << 5); uint8_t fu = type; if (first) { @@ -184,7 +184,7 @@ void _rtpv_process_nalu(rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t if (last) { fu |= 0x40; } - DG[RTP_HEADER_SIZE + 1] = fu; + DG[US_RTP_HEADER_SIZE + 1] = fu; memcpy(DG + fu_overhead, src, frag_size); rtpv->rtp->used = fu_overhead + frag_size; @@ -200,8 +200,8 @@ void _rtpv_process_nalu(rtpv_s *rtpv, const uint8_t *data, size_t size, uint32_t static ssize_t _find_annexb(const uint8_t *data, size_t size) { // Parses buffer for 00 00 01 start codes - if (size >= PRE) { - for (size_t index = 0; index <= size - PRE; ++index) { + if (size >= _PRE) { + for (size_t index = 0; index <= size - _PRE; ++index) { if (data[index] == 0 && data[index + 1] == 0 && data[index + 2] == 1) { return index; } @@ -210,4 +210,4 @@ static ssize_t _find_annexb(const uint8_t *data, size_t size) { return -1; } -#undef PRE +#undef _PRE diff --git a/janus/src/rtpv.h b/janus/src/rtpv.h index 53fbea7..81fc142 100644 --- a/janus/src/rtpv.h +++ b/janus/src/rtpv.h @@ -42,16 +42,16 @@ typedef struct { - rtp_s *rtp; - rtp_callback_f callback; - frame_s *sps; // Actually not a frame, just a bytes storage - frame_s *pps; - pthread_mutex_t mutex; -} rtpv_s; + us_rtp_s *rtp; + us_rtp_callback_f callback; + us_frame_s *sps; // Actually not a frame, just a bytes storage + us_frame_s *pps; + pthread_mutex_t mutex; +} us_rtpv_s; -rtpv_s *rtpv_init(rtp_callback_f callback, bool zero_playout_delay); -void rtpv_destroy(rtpv_s *rtpv); +us_rtpv_s *us_rtpv_init(us_rtp_callback_f callback, bool zero_playout_delay); +void us_rtpv_destroy(us_rtpv_s *rtpv); -char *rtpv_make_sdp(rtpv_s *rtpv); -void rtpv_wrap(rtpv_s *rtpv, const frame_s *frame); +char *us_rtpv_make_sdp(us_rtpv_s *rtpv); +void us_rtpv_wrap(us_rtpv_s *rtpv, const us_frame_s *frame); diff --git a/janus/src/tc358743.c b/janus/src/tc358743.c index d30844d..1648f35 100644 --- a/janus/src/tc358743.c +++ b/janus/src/tc358743.c @@ -34,24 +34,24 @@ #endif -int tc358743_read_info(const char *path, tc358743_info_s *info) { - MEMSET_ZERO(*info); +int us_tc358743_read_info(const char *path, us_tc358743_info_s *info) { + US_MEMSET_ZERO(*info); int fd = -1; if ((fd = open(path, O_RDWR)) < 0) { - JLOG_PERROR("audio", "Can't open TC358743 V4L2 device"); + US_JLOG_PERROR("audio", "Can't open TC358743 V4L2 device"); return -1; } -# define READ_CID(_cid, _field) { \ - struct v4l2_control ctl = {0}; \ - ctl.id = _cid; \ - if (xioctl(fd, VIDIOC_G_CTRL, &ctl) < 0) { \ - JLOG_PERROR("audio", "Can't get value of " #_cid); \ +# define READ_CID(x_cid, x_field) { \ + struct v4l2_control m_ctl = {0}; \ + m_ctl.id = x_cid; \ + if (us_xioctl(fd, VIDIOC_G_CTRL, &m_ctl) < 0) { \ + US_JLOG_PERROR("audio", "Can't get value of " #x_cid); \ close(fd); \ return -1; \ } \ - info->_field = ctl.value; \ + info->x_field = m_ctl.value; \ } READ_CID(TC358743_CID_AUDIO_PRESENT, has_audio); diff --git a/janus/src/tc358743.h b/janus/src/tc358743.h index 8d43fc9..4e3855d 100644 --- a/janus/src/tc358743.h +++ b/janus/src/tc358743.h @@ -40,7 +40,7 @@ typedef struct { bool has_audio; unsigned audio_hz; -} tc358743_info_s; +} us_tc358743_info_s; -int tc358743_read_info(const char *path, tc358743_info_s *info); +int us_tc358743_read_info(const char *path, us_tc358743_info_s *info); diff --git a/python/src/ustreamer.c b/python/src/ustreamer.c index 49813c9..8d724c4 100644 --- a/python/src/ustreamer.c +++ b/python/src/ustreamer.c @@ -27,21 +27,21 @@ typedef struct { double drop_same_frames; int fd; - memsink_shared_s *mem; + us_memsink_shared_s *mem; uint64_t frame_id; long double frame_ts; - frame_s *frame; -} MemsinkObject; + us_frame_s *frame; +} _MemsinkObject; -#define MEM(_next) self->mem->_next -#define FRAME(_next) self->frame->_next +#define _MEM(_next) self->mem->_next +#define _FRAME(_next) self->frame->_next -static void MemsinkObject_destroy_internals(MemsinkObject *self) { +static void _MemsinkObject_destroy_internals(_MemsinkObject *self) { if (self->mem != NULL) { - memsink_shared_unmap(self->mem); + us_memsink_shared_unmap(self->mem); self->mem = NULL; } if (self->fd > 0) { @@ -49,12 +49,12 @@ static void MemsinkObject_destroy_internals(MemsinkObject *self) { self->fd = -1; } if (self->frame) { - frame_destroy(self->frame); + us_frame_destroy(self->frame); self->frame = NULL; } } -static int MemsinkObject_init(MemsinkObject *self, PyObject *args, PyObject *kwargs) { +static int _MemsinkObject_init(_MemsinkObject *self, PyObject *args, PyObject *kwargs) { self->lock_timeout = 1; self->wait_timeout = 1; @@ -78,14 +78,14 @@ static int MemsinkObject_init(MemsinkObject *self, PyObject *args, PyObject *kwa # undef SET_DOUBLE - self->frame = frame_init(); + self->frame = us_frame_init(); if ((self->fd = shm_open(self->obj, O_RDWR, 0)) == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } - if ((self->mem = memsink_shared_map(self->fd)) == NULL) { + if ((self->mem = us_memsink_shared_map(self->fd)) == NULL) { PyErr_SetFromErrno(PyExc_OSError); goto error; } @@ -93,37 +93,37 @@ static int MemsinkObject_init(MemsinkObject *self, PyObject *args, PyObject *kwa return 0; error: - MemsinkObject_destroy_internals(self); + _MemsinkObject_destroy_internals(self); return -1; } -static PyObject *MemsinkObject_repr(MemsinkObject *self) { +static PyObject *_MemsinkObject_repr(_MemsinkObject *self) { char repr[1024]; snprintf(repr, 1023, "", self->obj); return Py_BuildValue("s", repr); } -static void MemsinkObject_dealloc(MemsinkObject *self) { - MemsinkObject_destroy_internals(self); +static void _MemsinkObject_dealloc(_MemsinkObject *self) { + _MemsinkObject_destroy_internals(self); PyObject_Del(self); } -static PyObject *MemsinkObject_close(MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { - MemsinkObject_destroy_internals(self); +static PyObject *_MemsinkObject_close(_MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { + _MemsinkObject_destroy_internals(self); Py_RETURN_NONE; } -static PyObject *MemsinkObject_enter(MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { +static PyObject *_MemsinkObject_enter(_MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { Py_INCREF(self); return (PyObject *)self; } -static PyObject *MemsinkObject_exit(MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { +static PyObject *_MemsinkObject_exit(_MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { return PyObject_CallMethod((PyObject *)self, "close", ""); } -static int wait_frame(MemsinkObject *self) { - long double deadline_ts = get_now_monotonic() + self->wait_timeout; +static int _wait_frame(_MemsinkObject *self) { + long double deadline_ts = us_get_now_monotonic() + self->wait_timeout; # define RETURN_OS_ERROR { \ Py_BLOCK_THREADS \ @@ -135,21 +135,21 @@ static int wait_frame(MemsinkObject *self) { do { Py_BEGIN_ALLOW_THREADS - int retval = flock_timedwait_monotonic(self->fd, self->lock_timeout); - now = get_now_monotonic(); + int retval = us_flock_timedwait_monotonic(self->fd, self->lock_timeout); + now = us_get_now_monotonic(); if (retval < 0 && errno != EWOULDBLOCK) { RETURN_OS_ERROR; } else if (retval == 0) { - if (MEM(magic) == MEMSINK_MAGIC && MEM(version) == MEMSINK_VERSION && MEM(id) != self->frame_id) { + if (_MEM(magic) == US_MEMSINK_MAGIC && _MEM(version) == US_MEMSINK_VERSION && _MEM(id) != self->frame_id) { if (self->drop_same_frames > 0) { if ( - FRAME_COMPARE_META_USED_NOTS(self->mem, self->frame) + US_FRAME_COMPARE_META_USED_NOTS(self->mem, self->frame) && (self->frame_ts + self->drop_same_frames > now) - && !memcmp(FRAME(data), MEM(data), MEM(used)) + && !memcmp(_FRAME(data), _MEM(data), _MEM(used)) ) { - self->frame_id = MEM(id); + self->frame_id = _MEM(id); goto drop; } } @@ -181,23 +181,23 @@ static int wait_frame(MemsinkObject *self) { return -2; } -static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { +static PyObject *_MemsinkObject_wait_frame(_MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { if (self->mem == NULL || self->fd <= 0) { PyErr_SetString(PyExc_RuntimeError, "Closed"); return NULL; } - switch (wait_frame(self)) { + switch (_wait_frame(self)) { case 0: break; case -2: Py_RETURN_NONE; default: return NULL; } - frame_set_data(self->frame, MEM(data), MEM(used)); - FRAME_COPY_META(self->mem, self->frame); - self->frame_id = MEM(id); - self->frame_ts = get_now_monotonic(); - MEM(last_client_ts) = self->frame_ts; + us_frame_set_data(self->frame, _MEM(data), _MEM(used)); + US_FRAME_COPY_META(self->mem, self->frame); + self->frame_id = _MEM(id); + self->frame_ts = us_get_now_monotonic(); + _MEM(last_client_ts) = self->frame_ts; if (flock(self->fd, LOCK_UN) < 0) { return PyErr_SetFromErrno(PyExc_OSError); @@ -219,7 +219,7 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS } \ Py_DECREF(_tmp); \ } -# define SET_NUMBER(_key, _from, _to) SET_VALUE(#_key, Py##_to##_From##_from(FRAME(_key))) +# define SET_NUMBER(_key, _from, _to) SET_VALUE(#_key, Py##_to##_From##_from(_FRAME(_key))) SET_NUMBER(width, Long, Long); SET_NUMBER(height, Long, Long); @@ -230,7 +230,7 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS SET_NUMBER(grab_ts, Double, Float); SET_NUMBER(encode_begin_ts, Double, Float); SET_NUMBER(encode_end_ts, Double, Float); - SET_VALUE("data", PyBytes_FromStringAndSize((const char *)FRAME(data), FRAME(used))); + SET_VALUE("data", PyBytes_FromStringAndSize((const char *)_FRAME(data), _FRAME(used))); # undef SET_NUMBER # undef SET_VALUE @@ -238,12 +238,12 @@ static PyObject *MemsinkObject_wait_frame(MemsinkObject *self, PyObject *Py_UNUS return dict_frame; } -static PyObject *MemsinkObject_is_opened(MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { +static PyObject *_MemsinkObject_is_opened(_MemsinkObject *self, PyObject *Py_UNUSED(ignored)) { return PyBool_FromLong(self->mem != NULL && self->fd > 0); } #define FIELD_GETTER(_field, _from, _to) \ - static PyObject *MemsinkObject_getter_##_field(MemsinkObject *self, void *Py_UNUSED(closure)) { \ + static PyObject *_MemsinkObject_getter_##_field(_MemsinkObject *self, void *Py_UNUSED(closure)) { \ return Py##_to##_From##_from(self->_field); \ } @@ -254,9 +254,9 @@ FIELD_GETTER(drop_same_frames, Double, Float) #undef FIELD_GETTER -static PyMethodDef MemsinkObject_methods[] = { +static PyMethodDef _MemsinkObject_methods[] = { # define ADD_METHOD(_name, _method, _flags) \ - {.ml_name = _name, .ml_meth = (PyCFunction)MemsinkObject_##_method, .ml_flags = (_flags)} + {.ml_name = _name, .ml_meth = (PyCFunction)_MemsinkObject_##_method, .ml_flags = (_flags)} ADD_METHOD("close", close, METH_NOARGS), ADD_METHOD("__enter__", enter, METH_NOARGS), ADD_METHOD("__exit__", exit, METH_VARARGS), @@ -266,8 +266,8 @@ static PyMethodDef MemsinkObject_methods[] = { # undef ADD_METHOD }; -static PyGetSetDef MemsinkObject_getsets[] = { -# define ADD_GETTER(_field) {.name = #_field, .get = (getter)MemsinkObject_getter_##_field} +static PyGetSetDef _MemsinkObject_getsets[] = { +# define ADD_GETTER(_field) {.name = #_field, .get = (getter)_MemsinkObject_getter_##_field} ADD_GETTER(obj), ADD_GETTER(lock_timeout), ADD_GETTER(wait_timeout), @@ -276,43 +276,40 @@ static PyGetSetDef MemsinkObject_getsets[] = { # undef ADD_GETTER }; -static PyTypeObject MemsinkType = { +static PyTypeObject _MemsinkType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "ustreamer.Memsink", - .tp_basicsize = sizeof(MemsinkObject), + .tp_basicsize = sizeof(_MemsinkObject), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, - .tp_init = (initproc)MemsinkObject_init, - .tp_dealloc = (destructor)MemsinkObject_dealloc, - .tp_repr = (reprfunc)MemsinkObject_repr, - .tp_methods = MemsinkObject_methods, - .tp_getset = MemsinkObject_getsets, + .tp_init = (initproc)_MemsinkObject_init, + .tp_dealloc = (destructor)_MemsinkObject_dealloc, + .tp_repr = (reprfunc)_MemsinkObject_repr, + .tp_methods = _MemsinkObject_methods, + .tp_getset = _MemsinkObject_getsets, }; -static PyModuleDef ustreamer_Module = { +static PyModuleDef _Module = { PyModuleDef_HEAD_INIT, .m_name = "ustreamer", .m_size = -1, }; PyMODINIT_FUNC PyInit_ustreamer(void) { // cppcheck-suppress unusedFunction - PyObject *module = PyModule_Create(&ustreamer_Module); + PyObject *module = PyModule_Create(&_Module); if (module == NULL) { return NULL; } - if (PyType_Ready(&MemsinkType) < 0) { + if (PyType_Ready(&_MemsinkType) < 0) { return NULL; } - Py_INCREF(&MemsinkType); + Py_INCREF(&_MemsinkType); - if (PyModule_AddObject(module, "Memsink", (PyObject *)&MemsinkType) < 0) { + if (PyModule_AddObject(module, "Memsink", (PyObject *)&_MemsinkType) < 0) { return NULL; } return module; } - -#undef FRAME -#undef MEM diff --git a/src/dump/file.c b/src/dump/file.c index 8213859..f4d1883 100644 --- a/src/dump/file.c +++ b/src/dump/file.c @@ -23,17 +23,17 @@ #include "file.h" -output_file_s *output_file_init(const char *path, bool json) { - output_file_s *output; - A_CALLOC(output, 1); +us_output_file_s *us_output_file_init(const char *path, bool json) { + us_output_file_s *output; + US_CALLOC(output, 1); if (!strcmp(path, "-")) { - LOG_INFO("Using output: "); + US_LOG_INFO("Using output: "); output->fp = stdout; } else { - LOG_INFO("Using output: %s", path); + US_LOG_INFO("Using output: %s", path); if ((output->fp = fopen(path, "wb")) == NULL) { - LOG_PERROR("Can't open output file"); + US_LOG_PERROR("Can't open output file"); goto error; } } @@ -42,14 +42,14 @@ output_file_s *output_file_init(const char *path, bool json) { return output; error: - output_file_destroy(output); + us_output_file_destroy(output); return NULL; } -void output_file_write(void *v_output, const frame_s *frame) { - output_file_s *output = (output_file_s *)v_output; +void us_output_file_write(void *v_output, const us_frame_s *frame) { + us_output_file_s *output = (us_output_file_s *)v_output; if (output->json) { - base64_encode(frame->data, frame->used, &output->base64_data, &output->base64_allocated); + us_base64_encode(frame->data, frame->used, &output->base64_data, &output->base64_allocated); fprintf(output->fp, "{\"size\": %zu, \"width\": %u, \"height\": %u," " \"format\": %u, \"stride\": %u, \"online\": %u," @@ -65,14 +65,14 @@ void output_file_write(void *v_output, const frame_s *frame) { fflush(output->fp); } -void output_file_destroy(void *v_output) { - output_file_s *output = (output_file_s *)v_output; +void us_output_file_destroy(void *v_output) { + us_output_file_s *output = (us_output_file_s *)v_output; if (output->base64_data) { free(output->base64_data); } if (output->fp && output->fp != stdout) { if (fclose(output->fp) < 0) { - LOG_PERROR("Can't close output file"); + US_LOG_PERROR("Can't close output file"); } } free(output); diff --git a/src/dump/file.h b/src/dump/file.h index 55975e1..a90f5f4 100644 --- a/src/dump/file.h +++ b/src/dump/file.h @@ -41,9 +41,9 @@ typedef struct { FILE *fp; char *base64_data; size_t base64_allocated; -} output_file_s; +} us_output_file_s; -output_file_s *output_file_init(const char *path, bool json); -void output_file_write(void *v_output, const frame_s *frame); -void output_file_destroy(void *v_output); +us_output_file_s *us_output_file_init(const char *path, bool json); +void us_output_file_write(void *v_output, const us_frame_s *frame); +void us_output_file_destroy(void *v_output); diff --git a/src/dump/main.c b/src/dump/main.c index 5602841..1614d8d 100644 --- a/src/dump/main.c +++ b/src/dump/main.c @@ -82,12 +82,12 @@ static const struct option _LONG_OPTS[] = { }; -volatile bool global_stop = false; +volatile bool _g_stop = false; typedef struct { void *v_output; - void (*write)(void *v_output, const frame_s *frame); + void (*write)(void *v_output, const us_frame_s *frame); void (*destroy)(void *v_output); } _output_context_s; @@ -104,8 +104,8 @@ static void _help(FILE *fp); int main(int argc, char *argv[]) { - LOGGING_INIT; - A_THREAD_RENAME("main"); + US_LOGGING_INIT; + US_THREAD_RENAME("main"); char *sink_name = NULL; unsigned sink_timeout = 1; @@ -140,7 +140,7 @@ int main(int argc, char *argv[]) { } char short_opts[128]; - build_short_options(_LONG_OPTS, short_opts, 128); + us_build_short_options(_LONG_OPTS, short_opts, 128); for (int ch; (ch = getopt_long(argc, argv, short_opts, _LONG_OPTS, NULL)) >= 0;) { switch (ch) { @@ -151,15 +151,15 @@ int main(int argc, char *argv[]) { case _O_COUNT: OPT_NUMBER("--count", count, 0, LLONG_MAX, 0); case _O_INTERVAL: OPT_LDOUBLE("--interval", interval, 0, 60); - case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, 0); - case _O_PERF: OPT_SET(us_log_level, LOG_LEVEL_PERF); - case _O_VERBOSE: OPT_SET(us_log_level, LOG_LEVEL_VERBOSE); - case _O_DEBUG: OPT_SET(us_log_level, LOG_LEVEL_DEBUG); + case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0); + case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF); + case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE); + case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG); case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true); case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false); case _O_HELP: _help(stdout); return 0; - case _O_VERSION: puts(VERSION); return 0; + case _O_VERSION: puts(US_VERSION); return 0; case 0: break; default: return 1; @@ -178,11 +178,11 @@ int main(int argc, char *argv[]) { _output_context_s ctx = {0}; if (output_path && output_path[0] != '\0') { - if ((ctx.v_output = (void *)output_file_init(output_path, output_json)) == NULL) { + if ((ctx.v_output = (void *)us_output_file_init(output_path, output_json)) == NULL) { return 1; } - ctx.write = output_file_write; - ctx.destroy = output_file_destroy; + ctx.write = us_output_file_write; + ctx.destroy = us_output_file_destroy; } _install_signal_handlers(); @@ -196,12 +196,12 @@ int main(int argc, char *argv[]) { static void _signal_handler(int signum) { switch (signum) { - case SIGTERM: LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break; - case SIGINT: LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break; - case SIGPIPE: LOG_INFO_NOLOCK("===== Stopping by SIGPIPE ====="); break; - default: LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break; + case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break; + case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break; + case SIGPIPE: US_LOG_INFO_NOLOCK("===== Stopping by SIGPIPE ====="); break; + default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break; } - global_stop = true; + _g_stop = true; } static void _install_signal_handlers(void) { @@ -213,13 +213,13 @@ static void _install_signal_handlers(void) { assert(!sigaddset(&sig_act.sa_mask, SIGTERM)); assert(!sigaddset(&sig_act.sa_mask, SIGPIPE)); - LOG_DEBUG("Installing SIGINT handler ..."); + US_LOG_DEBUG("Installing SIGINT handler ..."); assert(!sigaction(SIGINT, &sig_act, NULL)); - LOG_DEBUG("Installing SIGTERM handler ..."); + US_LOG_DEBUG("Installing SIGTERM handler ..."); assert(!sigaction(SIGTERM, &sig_act, NULL)); - LOG_DEBUG("Installing SIGTERM handler ..."); + US_LOG_DEBUG("Installing SIGTERM handler ..."); assert(!sigaction(SIGPIPE, &sig_act, NULL)); } @@ -234,10 +234,10 @@ static int _dump_sink( useconds_t interval_us = interval * 1000000; - frame_s *frame = frame_init(); - memsink_s *sink = NULL; + us_frame_s *frame = us_frame_init(); + us_memsink_s *sink = NULL; - if ((sink = memsink_init("input", sink_name, false, 0, false, 0, sink_timeout)) == NULL) { + if ((sink = us_memsink_init("input", sink_name, false, 0, false, 0, sink_timeout)) == NULL) { goto error; } @@ -247,28 +247,28 @@ static int _dump_sink( long double last_ts = 0; - while (!global_stop) { - int error = memsink_client_get(sink, frame); + while (!_g_stop) { + int error = us_memsink_client_get(sink, frame); if (error == 0) { - const long double now = get_now_monotonic(); - const long long now_second = floor_ms(now); + const long double now = us_get_now_monotonic(); + const long long now_second = us_floor_ms(now); char fourcc_str[8]; - LOG_VERBOSE("Frame: size=%zu, res=%ux%u, fourcc=%s, stride=%u, online=%d, key=%d, latency=%.3Lf, diff=%.3Lf", + US_LOG_VERBOSE("Frame: size=%zu, res=%ux%u, fourcc=%s, stride=%u, online=%d, key=%d, latency=%.3Lf, diff=%.3Lf", frame->used, frame->width, frame->height, - fourcc_to_string(frame->format, fourcc_str, 8), + us_fourcc_to_string(frame->format, fourcc_str, 8), frame->stride, frame->online, frame->key, now - frame->grab_ts, (last_ts ? now - last_ts : 0)); last_ts = now; - LOG_DEBUG(" grab_ts=%.3Lf, encode_begin_ts=%.3Lf, encode_end_ts=%.3Lf", + US_LOG_DEBUG(" grab_ts=%.3Lf, encode_begin_ts=%.3Lf, encode_end_ts=%.3Lf", frame->grab_ts, frame->encode_begin_ts, frame->encode_end_ts); if (now_second != fps_second) { fps = fps_accum; fps_accum = 0; fps_second = now_second; - LOG_PERF_FPS("A new second has come; captured_fps=%u", fps); + US_LOG_PERF_FPS("A new second has come; captured_fps=%u", fps); } fps_accum += 1; @@ -301,11 +301,11 @@ static int _dump_sink( ok: if (sink) { - memsink_destroy(sink); + us_memsink_destroy(sink); } - frame_destroy(frame); + us_frame_destroy(frame); - LOG_INFO("Bye-bye"); + US_LOG_INFO("Bye-bye"); return retval; } @@ -313,7 +313,7 @@ static void _help(FILE *fp) { # define SAY(_msg, ...) fprintf(fp, _msg "\n", ##__VA_ARGS__) SAY("\nuStreamer-dump - Dump uStreamer's memory sink to file"); SAY("═════════════════════════════════════════════════════"); - SAY("Version: %s; license: GPLv3", VERSION); + SAY("Version: %s; license: GPLv3", US_VERSION); SAY("Copyright (C) 2018-2022 Maxim Devaev \n"); SAY("Example:"); SAY("════════"); diff --git a/src/libs/base64.c b/src/libs/base64.c index 928d11b..d868344 100644 --- a/src/libs/base64.c +++ b/src/libs/base64.c @@ -37,11 +37,11 @@ static const char _ENCODING_TABLE[] = { static const unsigned _MOD_TABLE[] = {0, 2, 1}; -void base64_encode(const uint8_t *data, size_t size, char **encoded, size_t *allocated) { +void us_base64_encode(const uint8_t *data, size_t size, char **encoded, size_t *allocated) { const size_t encoded_size = 4 * ((size + 2) / 3) + 1; // +1 for '\0' if (*encoded == NULL || (allocated && *allocated < encoded_size)) { - A_REALLOC(*encoded, encoded_size); + US_REALLOC(*encoded, encoded_size); if (allocated) { *allocated = encoded_size; } diff --git a/src/libs/base64.h b/src/libs/base64.h index 99cdfdd..f9f076a 100644 --- a/src/libs/base64.h +++ b/src/libs/base64.h @@ -31,4 +31,4 @@ #include "tools.h" -void base64_encode(const uint8_t *data, size_t size, char **encoded, size_t *allocated); +void us_base64_encode(const uint8_t *data, size_t size, char **encoded, size_t *allocated); diff --git a/src/libs/const.h b/src/libs/const.h index 818e0a0..9e35fde 100644 --- a/src/libs/const.h +++ b/src/libs/const.h @@ -22,11 +22,11 @@ #pragma once -#define VERSION_MAJOR 5 -#define VERSION_MINOR 16 +#define US_VERSION_MAJOR 5 +#define US_VERSION_MINOR 16 -#define MAKE_VERSION2(_major, _minor) #_major "." #_minor -#define MAKE_VERSION1(_major, _minor) MAKE_VERSION2(_major, _minor) -#define VERSION MAKE_VERSION1(VERSION_MAJOR, VERSION_MINOR) +#define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor +#define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor) +#define US_VERSION US_MAKE_VERSION1(US_VERSION_MAJOR, US_VERSION_MINOR) -#define VERSION_U ((unsigned)(VERSION_MAJOR * 1000 + VERSION_MINOR)) +#define US_VERSION_U ((unsigned)(US_VERSION_MAJOR * 1000 + US_VERSION_MINOR)) diff --git a/src/libs/frame.c b/src/libs/frame.c index e4076d1..dfc12f1 100644 --- a/src/libs/frame.c +++ b/src/libs/frame.c @@ -23,55 +23,55 @@ #include "frame.h" -frame_s *frame_init(void) { - frame_s *frame; - A_CALLOC(frame, 1); - frame_realloc_data(frame, 512 * 1024); +us_frame_s *us_frame_init(void) { + us_frame_s *frame; + US_CALLOC(frame, 1); + us_frame_realloc_data(frame, 512 * 1024); frame->dma_fd = -1; return frame; } -void frame_destroy(frame_s *frame) { +void us_frame_destroy(us_frame_s *frame) { if (frame->data) { free(frame->data); } free(frame); } -void frame_realloc_data(frame_s *frame, size_t size) { +void us_frame_realloc_data(us_frame_s *frame, size_t size) { if (frame->allocated < size) { - A_REALLOC(frame->data, size); + US_REALLOC(frame->data, size); frame->allocated = size; } } -void frame_set_data(frame_s *frame, const uint8_t *data, size_t size) { - frame_realloc_data(frame, size); +void us_frame_set_data(us_frame_s *frame, const uint8_t *data, size_t size) { + us_frame_realloc_data(frame, size); memcpy(frame->data, data, size); frame->used = size; } -void frame_append_data(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; - frame_realloc_data(frame, new_used); + us_frame_realloc_data(frame, new_used); memcpy(frame->data + frame->used, data, size); frame->used = new_used; } -void frame_copy(const frame_s *src, frame_s *dest) { - frame_set_data(dest, src->data, src->used); - FRAME_COPY_META(src, dest); +void us_frame_copy(const us_frame_s *src, us_frame_s *dest) { + us_frame_set_data(dest, src->data, src->used); + US_FRAME_COPY_META(src, dest); } -bool frame_compare(const frame_s *a, const frame_s *b) { +bool us_frame_compare(const us_frame_s *a, const us_frame_s *b) { return ( a->allocated && b->allocated - && FRAME_COMPARE_META_USED_NOTS(a, b) + && US_FRAME_COMPARE_META_USED_NOTS(a, b) && !memcmp(a->data, b->data, b->used) ); } -unsigned frame_get_padding(const frame_s *frame) { +unsigned us_frame_get_padding(const us_frame_s *frame) { unsigned bytes_per_pixel = 0; switch (frame->format) { case V4L2_PIX_FMT_YUYV: @@ -89,7 +89,7 @@ unsigned frame_get_padding(const frame_s *frame) { return 0; } -const char *fourcc_to_string(unsigned format, char *buf, size_t size) { +const char *us_fourcc_to_string(unsigned format, char *buf, size_t size) { assert(size >= 8); buf[0] = format & 0x7F; buf[1] = (format >> 8) & 0x7F; diff --git a/src/libs/frame.h b/src/libs/frame.h index a9d444c..9760555 100644 --- a/src/libs/frame.h +++ b/src/libs/frame.h @@ -35,84 +35,84 @@ typedef struct { - uint8_t *data; - size_t used; - size_t allocated; - int dma_fd; + uint8_t *data; + size_t used; + size_t allocated; + int dma_fd; - unsigned width; - unsigned height; - unsigned format; - unsigned stride; + unsigned width; + unsigned height; + unsigned format; + unsigned stride; // Stride is a bytesperline in V4L2 // https://www.kernel.org/doc/html/v4.14/media/uapi/v4l/pixfmt-v4l2.html // https://medium.com/@oleg.shipitko/what-does-stride-mean-in-image-processing-bba158a72bcd - bool online; - bool key; + bool online; + bool key; long double grab_ts; long double encode_begin_ts; long double encode_end_ts; -} frame_s; +} us_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 US_FRAME_COPY_META(x_src, x_dest) { \ + x_dest->width = x_src->width; \ + x_dest->height = x_src->height; \ + x_dest->format = x_src->format; \ + x_dest->stride = x_src->stride; \ + x_dest->online = x_src->online; \ + x_dest->key = x_src->key; \ + x_dest->grab_ts = x_src->grab_ts; \ + x_dest->encode_begin_ts = x_src->encode_begin_ts; \ + x_dest->encode_end_ts = x_src->encode_end_ts; \ } -static inline void frame_copy_meta(const frame_s *src, frame_s *dest) { - FRAME_COPY_META(src, dest); +static inline void us_frame_copy_meta(const us_frame_s *src, us_frame_s *dest) { + US_FRAME_COPY_META(src, dest); } -#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 \ +#define US_FRAME_COMPARE_META_USED_NOTS(x_a, x_b) ( \ + x_a->used == x_b->used \ + && x_a->width == x_b->width \ + && x_a->height == x_b->height \ + && x_a->format == x_b->format \ + && x_a->stride == x_b->stride \ + && x_a->online == x_b->online \ + && x_a->key == x_b->key \ ) -static inline void frame_encoding_begin(const frame_s *src, frame_s *dest, unsigned format) { +static inline void us_frame_encoding_begin(const us_frame_s *src, us_frame_s *dest, unsigned format) { assert(src->used > 0); - frame_copy_meta(src, dest); - dest->encode_begin_ts = get_now_monotonic(); + us_frame_copy_meta(src, dest); + dest->encode_begin_ts = us_get_now_monotonic(); dest->format = format; dest->stride = 0; dest->used = 0; } -static inline void frame_encoding_end(frame_s *dest) { +static inline void us_frame_encoding_end(us_frame_s *dest) { assert(dest->used > 0); - dest->encode_end_ts = get_now_monotonic(); + dest->encode_end_ts = us_get_now_monotonic(); } -frame_s *frame_init(void); -void frame_destroy(frame_s *frame); +us_frame_s *us_frame_init(void); +void us_frame_destroy(us_frame_s *frame); -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 us_frame_realloc_data(us_frame_s *frame, size_t size); +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); -void frame_copy(const frame_s *src, frame_s *dest); -bool frame_compare(const frame_s *a, const frame_s *b); +void us_frame_copy(const us_frame_s *src, us_frame_s *dest); +bool us_frame_compare(const us_frame_s *a, const us_frame_s *b); -unsigned frame_get_padding(const frame_s *frame); +unsigned us_frame_get_padding(const us_frame_s *frame); -const char *fourcc_to_string(unsigned format, char *buf, size_t size); +const char *us_fourcc_to_string(unsigned format, char *buf, size_t size); -static inline bool is_jpeg(unsigned format) { +static inline bool us_is_jpeg(unsigned format) { return (format == V4L2_PIX_FMT_JPEG || format == V4L2_PIX_FMT_MJPEG); } diff --git a/src/libs/list.h b/src/libs/list.h index 8174d67..6e6556c 100644 --- a/src/libs/list.h +++ b/src/libs/list.h @@ -25,47 +25,47 @@ #include -#define LIST_STRUCT(...) \ +#define US_LIST_STRUCT(...) \ __VA_ARGS__ *prev; \ __VA_ARGS__ *next; -#define LIST_ITERATE(_first, _item, ...) { \ - for (__typeof__(_first) _item = _first; _item;) { \ - __typeof__(_first) _next = _item->next; \ +#define US_LIST_ITERATE(x_first, x_item, ...) { \ + for (__typeof__(x_first) x_item = x_first; x_item;) { \ + __typeof__(x_first) m_next = x_item->next; \ __VA_ARGS__ \ - _item = _next; \ + x_item = m_next; \ } \ } -#define LIST_APPEND(_first, _item) { \ - if (_first == NULL) { \ - _first = _item; \ +#define US_LIST_APPEND(x_first, x_item) { \ + if (x_first == NULL) { \ + x_first = x_item; \ } else { \ - __typeof__(_first) _last = _first; \ - for (; _last->next; _last = _last->next); \ - _item->prev = _last; \ - _last->next = _item; \ + __typeof__(x_first) m_last = x_first; \ + for (; m_last->next; m_last = m_last->next); \ + x_item->prev = m_last; \ + m_last->next = x_item; \ } \ } -#define LIST_APPEND_C(_first, _item, _count) { \ - LIST_APPEND(_first, _item); \ - ++(_count); \ +#define US_LIST_APPEND_C(x_first, x_item, x_count) { \ + US_LIST_APPEND(x_first, x_item); \ + ++(x_count); \ } -#define LIST_REMOVE(_first, _item) { \ - if (_item->prev == NULL) { \ - _first = _item->next; \ +#define US_LIST_REMOVE(x_first, x_item) { \ + if (x_item->prev == NULL) { \ + x_first = x_item->next; \ } else { \ - _item->prev->next = _item->next; \ + x_item->prev->next = x_item->next; \ } \ - if (_item->next != NULL) { \ - _item->next->prev = _item->prev; \ + if (x_item->next != NULL) { \ + x_item->next->prev = x_item->prev; \ } \ } -#define LIST_REMOVE_C(_first, _item, _count) { \ - LIST_REMOVE(_first, _item); \ - assert((_count) >= 1); \ - --(_count); \ +#define US_LIST_REMOVE_C(x_first, x_item, x_count) { \ + US_LIST_REMOVE(x_first, x_item); \ + assert((x_count) >= 1); \ + --(x_count); \ } diff --git a/src/libs/logging.c b/src/libs/logging.c index b3c013b..57664f1 100644 --- a/src/libs/logging.c +++ b/src/libs/logging.c @@ -23,7 +23,7 @@ #include "logging.h" -enum log_level_t us_log_level; +enum us_log_level_t us_log_level; bool us_log_colored; diff --git a/src/libs/logging.h b/src/libs/logging.h index 253bc42..39867a1 100644 --- a/src/libs/logging.h +++ b/src/libs/logging.h @@ -37,126 +37,126 @@ #include "threading.h" -enum log_level_t { - LOG_LEVEL_INFO, - LOG_LEVEL_PERF, - LOG_LEVEL_VERBOSE, - LOG_LEVEL_DEBUG, +enum us_log_level_t { + US_LOG_LEVEL_INFO, + US_LOG_LEVEL_PERF, + US_LOG_LEVEL_VERBOSE, + US_LOG_LEVEL_DEBUG, }; -extern enum log_level_t us_log_level; +extern enum us_log_level_t us_log_level; extern bool us_log_colored; extern pthread_mutex_t us_log_mutex; -#define LOGGING_INIT { \ - us_log_level = LOG_LEVEL_INFO; \ +#define US_LOGGING_INIT { \ + us_log_level = US_LOG_LEVEL_INFO; \ us_log_colored = isatty(2); \ - A_MUTEX_INIT(&us_log_mutex); \ + US_MUTEX_INIT(&us_log_mutex); \ } -#define LOGGING_DESTROY A_MUTEX_DESTROY(&us_log_mutex) +#define US_LOGGING_DESTROY US_MUTEX_DESTROY(&us_log_mutex) -#define LOGGING_LOCK A_MUTEX_LOCK(&us_log_mutex) -#define LOGGING_UNLOCK A_MUTEX_UNLOCK(&us_log_mutex) +#define US_LOGGING_LOCK US_MUTEX_LOCK(&us_log_mutex) +#define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(&us_log_mutex) -#define COLOR_GRAY "\x1b[30;1m" -#define COLOR_RED "\x1b[31;1m" -#define COLOR_GREEN "\x1b[32;1m" -#define COLOR_YELLOW "\x1b[33;1m" -#define COLOR_BLUE "\x1b[34;1m" -#define COLOR_CYAN "\x1b[36;1m" -#define COLOR_RESET "\x1b[0m" +#define US_COLOR_GRAY "\x1b[30;1m" +#define US_COLOR_RED "\x1b[31;1m" +#define US_COLOR_GREEN "\x1b[32;1m" +#define US_COLOR_YELLOW "\x1b[33;1m" +#define US_COLOR_BLUE "\x1b[34;1m" +#define US_COLOR_CYAN "\x1b[36;1m" +#define US_COLOR_RESET "\x1b[0m" -#define SEP_INFO(_ch) { \ - LOGGING_LOCK; \ - for (int _i = 0; _i < 80; ++_i) { \ - fputc(_ch, stderr); \ +#define US_SEP_INFO(x_ch) { \ + US_LOGGING_LOCK; \ + for (int m_count = 0; m_count < 80; ++m_count) { \ + fputc((x_ch), stderr); \ } \ fputc('\n', stderr); \ fflush(stderr); \ - LOGGING_UNLOCK; \ + US_LOGGING_UNLOCK; \ } -#define SEP_DEBUG(_ch) { \ - if (us_log_level >= LOG_LEVEL_DEBUG) { \ - SEP_INFO(_ch); \ +#define US_SEP_DEBUG(x_ch) { \ + if (us_log_level >= US_LOG_LEVEL_DEBUG) { \ + US_SEP_INFO(x_ch); \ } \ } -#define LOG_PRINTF_NOLOCK(_label_color, _label, _msg_color, _msg, ...) { \ - char _tname_buf[MAX_THREAD_NAME] = {0}; \ - thread_get_name(_tname_buf); \ +#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \ + char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \ + us_thread_get_name(m_tname_buf); \ if (us_log_colored) { \ - fprintf(stderr, COLOR_GRAY "-- " _label_color _label COLOR_GRAY \ - " [%.03Lf %9s]" " -- " COLOR_RESET _msg_color _msg COLOR_RESET, \ - get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \ + fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \ + " [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \ + us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \ } else { \ - fprintf(stderr, "-- " _label " [%.03Lf %9s] -- " _msg, \ - get_now_monotonic(), _tname_buf, ##__VA_ARGS__); \ + fprintf(stderr, "-- " x_label " [%.03Lf %9s] -- " x_msg, \ + us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \ } \ fputc('\n', stderr); \ fflush(stderr); \ } -#define LOG_PRINTF(_label_color, _label, _msg_color, _msg, ...) { \ - LOGGING_LOCK; \ - LOG_PRINTF_NOLOCK(_label_color, _label, _msg_color, _msg, ##__VA_ARGS__); \ - LOGGING_UNLOCK; \ +#define US_LOG_PRINTF(x_label_color, x_label, x_msg_color, x_msg, ...) { \ + US_LOGGING_LOCK; \ + US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ##__VA_ARGS__); \ + US_LOGGING_UNLOCK; \ } -#define LOG_ERROR(_msg, ...) { \ - LOG_PRINTF(COLOR_RED, "ERROR", COLOR_RED, _msg, ##__VA_ARGS__); \ +#define US_LOG_ERROR(x_msg, ...) { \ + US_LOG_PRINTF(US_COLOR_RED, "ERROR", US_COLOR_RED, x_msg, ##__VA_ARGS__); \ } -#define LOG_PERROR(_msg, ...) { \ - char _perror_buf[1024] = {0}; \ - char *_perror_ptr = errno_to_string(errno, _perror_buf, 1024); \ - LOG_ERROR(_msg ": %s", ##__VA_ARGS__, _perror_ptr); \ +#define US_LOG_PERROR(x_msg, ...) { \ + char m_perror_buf[1024] = {0}; \ + char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1024); \ + US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \ } -#define LOG_INFO(_msg, ...) { \ - LOG_PRINTF(COLOR_GREEN, "INFO ", "", _msg, ##__VA_ARGS__); \ +#define US_LOG_INFO(x_msg, ...) { \ + US_LOG_PRINTF(US_COLOR_GREEN, "INFO ", "", x_msg, ##__VA_ARGS__); \ } -#define LOG_INFO_NOLOCK(_msg, ...) { \ - LOG_PRINTF_NOLOCK(COLOR_GREEN, "INFO ", "", _msg, ##__VA_ARGS__); \ +#define US_LOG_INFO_NOLOCK(x_msg, ...) { \ + US_LOG_PRINTF_NOLOCK(US_COLOR_GREEN, "INFO ", "", x_msg, ##__VA_ARGS__); \ } -#define LOG_PERF(_msg, ...) { \ - if (us_log_level >= LOG_LEVEL_PERF) { \ - LOG_PRINTF(COLOR_CYAN, "PERF ", COLOR_CYAN, _msg, ##__VA_ARGS__); \ +#define US_LOG_PERF(x_msg, ...) { \ + if (us_log_level >= US_LOG_LEVEL_PERF) { \ + US_LOG_PRINTF(US_COLOR_CYAN, "PERF ", US_COLOR_CYAN, x_msg, ##__VA_ARGS__); \ } \ } -#define LOG_PERF_FPS(_msg, ...) { \ - if (us_log_level >= LOG_LEVEL_PERF) { \ - LOG_PRINTF(COLOR_YELLOW, "PERF ", COLOR_YELLOW, _msg, ##__VA_ARGS__); \ +#define US_LOG_PERF_FPS(x_msg, ...) { \ + if (us_log_level >= US_LOG_LEVEL_PERF) { \ + US_LOG_PRINTF(US_COLOR_YELLOW, "PERF ", US_COLOR_YELLOW, x_msg, ##__VA_ARGS__); \ } \ } -#define LOG_VERBOSE(_msg, ...) { \ - if (us_log_level >= LOG_LEVEL_VERBOSE) { \ - LOG_PRINTF(COLOR_BLUE, "VERB ", COLOR_BLUE, _msg, ##__VA_ARGS__); \ +#define US_LOG_VERBOSE(x_msg, ...) { \ + if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \ + US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg, ##__VA_ARGS__); \ } \ } -#define LOG_VERBOSE_PERROR(_msg, ...) { \ - if (us_log_level >= LOG_LEVEL_VERBOSE) { \ - char _perror_buf[1024] = {0}; \ - char *_perror_ptr = errno_to_string(errno, _perror_buf, 1023); \ - LOG_PRINTF(COLOR_BLUE, "VERB ", COLOR_BLUE, _msg ": %s", ##__VA_ARGS__, _perror_ptr); \ +#define US_LOG_VERBOSE_PERROR(x_msg, ...) { \ + if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \ + char m_perror_buf[1024] = {0}; \ + char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \ + US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \ } \ } -#define LOG_DEBUG(_msg, ...) { \ - if (us_log_level >= LOG_LEVEL_DEBUG) { \ - LOG_PRINTF(COLOR_GRAY, "DEBUG", COLOR_GRAY, _msg, ##__VA_ARGS__); \ +#define US_LOG_DEBUG(x_msg, ...) { \ + if (us_log_level >= US_LOG_LEVEL_DEBUG) { \ + US_LOG_PRINTF(US_COLOR_GRAY, "DEBUG", US_COLOR_GRAY, x_msg, ##__VA_ARGS__); \ } \ } diff --git a/src/libs/memsink.c b/src/libs/memsink.c index 2be2671..9380a53 100644 --- a/src/libs/memsink.c +++ b/src/libs/memsink.c @@ -23,12 +23,12 @@ #include "memsink.h" -memsink_s *memsink_init( +us_memsink_s *us_memsink_init( const char *name, const char *obj, bool server, mode_t mode, bool rm, unsigned client_ttl, unsigned timeout) { - memsink_s *sink; - A_CALLOC(sink, 1); + us_memsink_s *sink; + US_CALLOC(sink, 1); sink->name = name; sink->obj = obj; sink->server = server; @@ -39,54 +39,54 @@ memsink_s *memsink_init( sink->mem = MAP_FAILED; atomic_init(&sink->has_clients, false); - LOG_INFO("Using %s-sink: %s", name, obj); + US_LOG_INFO("Using %s-sink: %s", name, obj); 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) { umask(mask); - LOG_PERROR("%s-sink: Can't open shared memory", name); + US_LOG_PERROR("%s-sink: Can't open shared memory", name); goto error; } - if (sink->server && ftruncate(sink->fd, sizeof(memsink_shared_s)) < 0) { - LOG_PERROR("%s-sink: Can't truncate shared memory", name); + if (sink->server && ftruncate(sink->fd, sizeof(us_memsink_shared_s)) < 0) { + US_LOG_PERROR("%s-sink: Can't truncate shared memory", name); goto error; } - if ((sink->mem = memsink_shared_map(sink->fd)) == NULL) { - LOG_PERROR("%s-sink: Can't mmap shared memory", name); + if ((sink->mem = us_memsink_shared_map(sink->fd)) == NULL) { + US_LOG_PERROR("%s-sink: Can't mmap shared memory", name); goto error; } return sink; error: - memsink_destroy(sink); + us_memsink_destroy(sink); return NULL; } -void memsink_destroy(memsink_s *sink) { +void us_memsink_destroy(us_memsink_s *sink) { if (sink->mem != MAP_FAILED) { - if (memsink_shared_unmap(sink->mem) < 0) { - LOG_PERROR("%s-sink: Can't unmap shared memory", sink->name); + if (us_memsink_shared_unmap(sink->mem) < 0) { + US_LOG_PERROR("%s-sink: Can't unmap shared memory", sink->name); } } if (sink->fd >= 0) { if (close(sink->fd) < 0) { - LOG_PERROR("%s-sink: Can't close shared memory fd", sink->name); + US_LOG_PERROR("%s-sink: Can't close shared memory fd", sink->name); } if (sink->rm && shm_unlink(sink->obj) < 0) { if (errno != ENOENT) { - LOG_PERROR("%s-sink: Can't remove shared memory", sink->name); + US_LOG_PERROR("%s-sink: Can't remove shared memory", sink->name); } } } free(sink); } -bool memsink_server_check(memsink_s *sink, const frame_s *frame) { +bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame) { // Return true (the need to write to memsink) on any of these conditions: // - EWOULDBLOCK - we have an active client; // - Incorrect magic or version - need to first write; @@ -100,97 +100,97 @@ bool memsink_server_check(memsink_s *sink, const frame_s *frame) { atomic_store(&sink->has_clients, true); return true; } - LOG_PERROR("%s-sink: Can't lock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't lock memory", sink->name); return false; } - if (sink->mem->magic != MEMSINK_MAGIC || sink->mem->version != MEMSINK_VERSION) { + if (sink->mem->magic != US_MEMSINK_MAGIC || sink->mem->version != US_MEMSINK_VERSION) { return true; } - bool has_clients = (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic()); + 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) { - LOG_PERROR("%s-sink: Can't unlock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't unlock memory", sink->name); return false; } - return (has_clients || !FRAME_COMPARE_META_USED_NOTS(sink->mem, frame));; + return (has_clients || !US_FRAME_COMPARE_META_USED_NOTS(sink->mem, frame));; } -int memsink_server_put(memsink_s *sink, const frame_s *frame) { +int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame) { assert(sink->server); - const long double now = get_now_monotonic(); + const long double now = us_get_now_monotonic(); - if (frame->used > MEMSINK_MAX_DATA) { - LOG_ERROR("%s-sink: Can't put frame: is too big (%zu > %zu)", - sink->name, frame->used, MEMSINK_MAX_DATA); + if (frame->used > US_MEMSINK_MAX_DATA) { + US_LOG_ERROR("%s-sink: Can't put frame: is too big (%zu > %zu)", + sink->name, frame->used, US_MEMSINK_MAX_DATA); return 0; // -2 } - if (flock_timedwait_monotonic(sink->fd, 1) == 0) { - LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name); + if (us_flock_timedwait_monotonic(sink->fd, 1) == 0) { + US_LOG_VERBOSE("%s-sink: >>>>> Exposing new frame ...", sink->name); - sink->last_id = get_now_id(); + sink->last_id = us_get_now_id(); sink->mem->id = sink->last_id; memcpy(sink->mem->data, frame->data, frame->used); sink->mem->used = frame->used; - FRAME_COPY_META(frame, sink->mem); + US_FRAME_COPY_META(frame, sink->mem); - sink->mem->magic = MEMSINK_MAGIC; - sink->mem->version = MEMSINK_VERSION; - atomic_store(&sink->has_clients, (sink->mem->last_client_ts + sink->client_ttl > get_now_monotonic())); + sink->mem->magic = US_MEMSINK_MAGIC; + sink->mem->version = US_MEMSINK_VERSION; + atomic_store(&sink->has_clients, (sink->mem->last_client_ts + sink->client_ttl > us_get_now_monotonic())); if (flock(sink->fd, LOCK_UN) < 0) { - LOG_PERROR("%s-sink: Can't unlock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't unlock memory", sink->name); return -1; } - LOG_VERBOSE("%s-sink: Exposed new frame; full exposition time = %.3Lf", - sink->name, get_now_monotonic() - now); + US_LOG_VERBOSE("%s-sink: Exposed new frame; full exposition time = %.3Lf", + sink->name, us_get_now_monotonic() - now); } else if (errno == EWOULDBLOCK) { - LOG_VERBOSE("%s-sink: ===== Shared memory is busy now; frame skipped", sink->name); + US_LOG_VERBOSE("%s-sink: ===== Shared memory is busy now; frame skipped", sink->name); } else { - LOG_PERROR("%s-sink: Can't lock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't lock memory", sink->name); return -1; } return 0; } -int memsink_client_get(memsink_s *sink, frame_s *frame) { // cppcheck-suppress unusedFunction +int us_memsink_client_get(us_memsink_s *sink, us_frame_s *frame) { // cppcheck-suppress unusedFunction assert(!sink->server); // Client only - if (flock_timedwait_monotonic(sink->fd, sink->timeout) < 0) { + if (us_flock_timedwait_monotonic(sink->fd, sink->timeout) < 0) { if (errno == EWOULDBLOCK) { return -2; } - LOG_PERROR("%s-sink: Can't lock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't lock memory", sink->name); return -1; } int retval = -2; // Not updated - if (sink->mem->magic == MEMSINK_MAGIC) { - if (sink->mem->version != MEMSINK_VERSION) { - LOG_ERROR("%s-sink: Protocol version mismatch: sink=%u, required=%u", - sink->name, sink->mem->version, MEMSINK_VERSION); + if (sink->mem->magic == US_MEMSINK_MAGIC) { + if (sink->mem->version != US_MEMSINK_VERSION) { + US_LOG_ERROR("%s-sink: Protocol version mismatch: sink=%u, required=%u", + sink->name, sink->mem->version, US_MEMSINK_VERSION); retval = -1; goto done; } if (sink->mem->id != sink->last_id) { // When updated sink->last_id = sink->mem->id; - frame_set_data(frame, sink->mem->data, sink->mem->used); - FRAME_COPY_META(sink->mem, frame); + us_frame_set_data(frame, sink->mem->data, sink->mem->used); + US_FRAME_COPY_META(sink->mem, frame); retval = 0; } - sink->mem->last_client_ts = get_now_monotonic(); + sink->mem->last_client_ts = us_get_now_monotonic(); } done: if (flock(sink->fd, LOCK_UN) < 0) { - LOG_PERROR("%s-sink: Can't unlock memory", sink->name); + US_LOG_PERROR("%s-sink: Can't unlock memory", sink->name); return -1; } return retval; diff --git a/src/libs/memsink.h b/src/libs/memsink.h index d09de9e..d38d45d 100644 --- a/src/libs/memsink.h +++ b/src/libs/memsink.h @@ -42,27 +42,27 @@ typedef struct { - const char *name; - const char *obj; - bool server; - bool rm; - unsigned client_ttl; // Only for server - unsigned timeout; + const char *name; + const char *obj; + bool server; + bool rm; + unsigned client_ttl; // Only for server + unsigned timeout; int fd; - memsink_shared_s *mem; + us_memsink_shared_s *mem; uint64_t last_id; atomic_bool has_clients; // Only for server -} memsink_s; +} us_memsink_s; -memsink_s *memsink_init( +us_memsink_s *us_memsink_init( const char *name, const char *obj, bool server, mode_t mode, bool rm, unsigned client_ttl, unsigned timeout); -void memsink_destroy(memsink_s *sink); +void us_memsink_destroy(us_memsink_s *sink); -bool memsink_server_check(memsink_s *sink, const frame_s *frame); -int memsink_server_put(memsink_s *sink, const frame_s *frame); +bool us_memsink_server_check(us_memsink_s *sink, const us_frame_s *frame); +int us_memsink_server_put(us_memsink_s *sink, const us_frame_s *frame); -int memsink_client_get(memsink_s *sink, frame_s *frame); +int us_memsink_client_get(us_memsink_s *sink, us_frame_s *frame); diff --git a/src/libs/memsinksh.h b/src/libs/memsinksh.h index 73b0da3..583f2b7 100644 --- a/src/libs/memsinksh.h +++ b/src/libs/memsinksh.h @@ -29,13 +29,13 @@ #include -#define MEMSINK_MAGIC ((uint64_t)0xCAFEBABECAFEBABE) -#define MEMSINK_VERSION ((uint32_t)2) +#define US_MEMSINK_MAGIC ((uint64_t)0xCAFEBABECAFEBABE) +#define US_MEMSINK_VERSION ((uint32_t)2) -#ifndef CFG_MEMSINK_MAX_DATA -# define CFG_MEMSINK_MAX_DATA 33554432 +#ifndef US_CFG_MEMSINK_MAX_DATA +# define US_CFG_MEMSINK_MAX_DATA 33554432 #endif -#define MEMSINK_MAX_DATA ((size_t)(CFG_MEMSINK_MAX_DATA)) +#define US_MEMSINK_MAX_DATA ((size_t)(US_CFG_MEMSINK_MAX_DATA)) typedef struct { @@ -58,14 +58,14 @@ typedef struct { long double last_client_ts; - uint8_t data[MEMSINK_MAX_DATA]; -} memsink_shared_s; + uint8_t data[US_MEMSINK_MAX_DATA]; +} us_memsink_shared_s; -INLINE memsink_shared_s *memsink_shared_map(int fd) { - memsink_shared_s *mem = mmap( +INLINE us_memsink_shared_s *us_memsink_shared_map(int fd) { + us_memsink_shared_s *mem = mmap( NULL, - sizeof(memsink_shared_s), + sizeof(us_memsink_shared_s), PROT_READ | PROT_WRITE, MAP_SHARED, fd, @@ -78,7 +78,7 @@ INLINE memsink_shared_s *memsink_shared_map(int fd) { return mem; } -INLINE int memsink_shared_unmap(memsink_shared_s *mem) { +INLINE int us_memsink_shared_unmap(us_memsink_shared_s *mem) { assert(mem != NULL); - return munmap(mem, sizeof(memsink_shared_s)); + return munmap(mem, sizeof(us_memsink_shared_s)); } diff --git a/src/libs/options.c b/src/libs/options.c index f58beb8..c3d42e1 100644 --- a/src/libs/options.c +++ b/src/libs/options.c @@ -23,7 +23,7 @@ #include "options.h" -void build_short_options(const struct option opts[], char *short_opts, size_t size) { +void us_build_short_options(const struct option opts[], char *short_opts, size_t size) { memset(short_opts, 0, size); for (unsigned short_index = 0, opt_index = 0; opts[opt_index].name != NULL; ++opt_index) { assert(short_index < size - 3); diff --git a/src/libs/options.h b/src/libs/options.h index c83a53e..9901caa 100644 --- a/src/libs/options.h +++ b/src/libs/options.h @@ -30,4 +30,4 @@ #include -void build_short_options(const struct option opts[], char *short_opts, size_t size); +void us_build_short_options(const struct option opts[], char *short_opts, size_t size); diff --git a/src/libs/process.h b/src/libs/process.h index 854b3ec..d8774ec 100644 --- a/src/libs/process.h +++ b/src/libs/process.h @@ -72,7 +72,7 @@ extern char **environ; #ifdef HAS_PDEATHSIG -INLINE int process_track_parent_death(void) { +INLINE int us_process_track_parent_death(void) { pid_t parent = getppid(); int signum = SIGTERM; # if defined(__linux__) @@ -83,12 +83,12 @@ INLINE int process_track_parent_death(void) { # error WTF? # endif if (retval < 0) { - LOG_PERROR("Can't set to receive SIGTERM on parent process death"); + US_LOG_PERROR("Can't set to receive SIGTERM on parent process death"); return -1; } if (kill(parent, 0) < 0) { - LOG_PERROR("The parent process %d is already dead", parent); + US_LOG_PERROR("The parent process %d is already dead", parent); return -1; } @@ -99,21 +99,21 @@ INLINE int process_track_parent_death(void) { #ifdef WITH_SETPROCTITLE # pragma GCC diagnostic ignored "-Wunused-parameter" # pragma GCC diagnostic push -INLINE void process_set_name_prefix(int argc, char *argv[], const char *prefix) { +INLINE void us_process_set_name_prefix(int argc, char *argv[], const char *prefix) { # pragma GCC diagnostic pop char *cmdline = NULL; size_t allocated = 2048; size_t used = 0; - A_REALLOC(cmdline, allocated); + US_REALLOC(cmdline, allocated); cmdline[0] = '\0'; for (int index = 0; index < argc; ++index) { size_t arg_len = strlen(argv[index]); if (used + arg_len + 16 >= allocated) { allocated += arg_len + 2048; - A_REALLOC(cmdline, allocated); // cppcheck-suppress memleakOnRealloc // False-positive (ok with assert) + US_REALLOC(cmdline, allocated); // cppcheck-suppress memleakOnRealloc // False-positive (ok with assert) } strcat(cmdline, " "); @@ -130,18 +130,18 @@ INLINE void process_set_name_prefix(int argc, char *argv[], const char *prefix) } #endif -INLINE void process_notify_parent(void) { +INLINE void us_process_notify_parent(void) { pid_t parent = getppid(); if (kill(parent, SIGUSR2) < 0) { - LOG_PERROR("Can't send SIGUSR2 to the parent process %d", parent); + US_LOG_PERROR("Can't send SIGUSR2 to the parent process %d", parent); } } -INLINE void process_suicide(void) { +INLINE void us_process_suicide(void) { pid_t pid = getpid(); if (kill(pid, SIGTERM) < 0) { - LOG_PERROR("Can't send SIGTERM to own pid %d", pid); + US_LOG_PERROR("Can't send SIGTERM to own pid %d", pid); } } diff --git a/src/libs/threading.h b/src/libs/threading.h index 924136f..e8e15e5 100644 --- a/src/libs/threading.h +++ b/src/libs/threading.h @@ -41,37 +41,37 @@ #ifdef PTHREAD_MAX_NAMELEN_NP -# define MAX_THREAD_NAME ((size_t)(PTHREAD_MAX_NAMELEN_NP)) +# define US_MAX_THREAD_NAME ((size_t)(PTHREAD_MAX_NAMELEN_NP)) #else -# define MAX_THREAD_NAME ((size_t)16) +# define US_MAX_THREAD_NAME ((size_t)16) #endif -#define A_THREAD_CREATE(_tid, _func, _arg) assert(!pthread_create(_tid, NULL, _func, _arg)) -#define A_THREAD_JOIN(_tid) assert(!pthread_join(_tid, NULL)) +#define US_THREAD_CREATE(x_tid, x_func, x_arg) assert(!pthread_create((x_tid), NULL, (x_func), (x_arg))) +#define US_THREAD_JOIN(x_tid) assert(!pthread_join((x_tid), NULL)) #ifdef WITH_PTHREAD_NP -# define A_THREAD_RENAME(_fmt, ...) { \ - char _new_tname_buf[MAX_THREAD_NAME] = {0}; \ - assert(snprintf(_new_tname_buf, MAX_THREAD_NAME, _fmt, ##__VA_ARGS__) > 0); \ - thread_set_name(_new_tname_buf); \ +# define US_THREAD_RENAME(x_fmt, ...) { \ + char m_new_tname_buf[US_MAX_THREAD_NAME] = {0}; \ + assert(snprintf(m_new_tname_buf, US_MAX_THREAD_NAME, (x_fmt), ##__VA_ARGS__) > 0); \ + us_thread_set_name(m_new_tname_buf); \ } #else -# define A_THREAD_RENAME(_fmt, ...) +# define US_THREAD_RENAME(_fmt, ...) #endif -#define A_MUTEX_INIT(_mutex) assert(!pthread_mutex_init(_mutex, NULL)) -#define A_MUTEX_DESTROY(_mutex) assert(!pthread_mutex_destroy(_mutex)) -#define A_MUTEX_LOCK(_mutex) assert(!pthread_mutex_lock(_mutex)) -#define A_MUTEX_UNLOCK(_mutex) assert(!pthread_mutex_unlock(_mutex)) +#define US_MUTEX_INIT(x_mutex) assert(!pthread_mutex_init((x_mutex), NULL)) +#define US_MUTEX_DESTROY(x_mutex) assert(!pthread_mutex_destroy(x_mutex)) +#define US_MUTEX_LOCK(x_mutex) assert(!pthread_mutex_lock(x_mutex)) +#define US_MUTEX_UNLOCK(x_mutex) assert(!pthread_mutex_unlock(x_mutex)) -#define A_COND_INIT(_cond) assert(!pthread_cond_init(_cond, NULL)) -#define A_COND_DESTROY(_cond) assert(!pthread_cond_destroy(_cond)) -#define A_COND_SIGNAL(...) assert(!pthread_cond_signal(__VA_ARGS__)) -#define A_COND_WAIT_TRUE(_var, _cond, _mutex) { while(!(_var)) assert(!pthread_cond_wait(_cond, _mutex)); } +#define US_COND_INIT(x_cond) assert(!pthread_cond_init((x_cond), NULL)) +#define US_COND_DESTROY(x_cond) assert(!pthread_cond_destroy(x_cond)) +#define US_COND_SIGNAL(...) assert(!pthread_cond_signal(__VA_ARGS__)) +#define US_COND_WAIT_TRUE(x_var, x_cond, x_mutex) { while(!(x_var)) assert(!pthread_cond_wait((x_cond), (x_mutex))); } #ifdef WITH_PTHREAD_NP -INLINE void thread_set_name(const char *name) { +INLINE void us_thread_set_name(const char *name) { # if defined(__linux__) pthread_setname_np(pthread_self(), name); # elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) @@ -79,26 +79,26 @@ INLINE void thread_set_name(const char *name) { # elif defined(__NetBSD__) pthread_setname_np(pthread_self(), "%s", (void *)name); # else -# error thread_set_name() not implemented, you can disable it using WITH_PTHREAD_NP=0 +# error us_thread_set_name() not implemented, you can disable it using WITH_PTHREAD_NP=0 # endif } #endif -INLINE void thread_get_name(char *name) { // Always required for logging +INLINE void us_thread_get_name(char *name) { // Always required for logging #ifdef WITH_PTHREAD_NP int retval = -1; # if defined(__linux__) || defined (__NetBSD__) - retval = pthread_getname_np(pthread_self(), name, MAX_THREAD_NAME); + retval = pthread_getname_np(pthread_self(), name, US_MAX_THREAD_NAME); # elif \ (defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1103500) \ || (defined(__OpenBSD__) && defined(OpenBSD) && OpenBSD >= 201905) \ || defined(__DragonFly__) - pthread_get_name_np(pthread_self(), name, MAX_THREAD_NAME); + pthread_get_name_np(pthread_self(), name, US_MAX_THREAD_NAME); if (name[0] != '\0') { retval = 0; } # else -# error thread_get_name() not implemented, you can disable it using WITH_PTHREAD_NP=0 +# error us_thread_get_name() not implemented, you can disable it using WITH_PTHREAD_NP=0 # endif if (retval < 0) { #endif @@ -117,7 +117,7 @@ INLINE void thread_get_name(char *name) { // Always required for logging pid_t tid = 0; // Makes cppcheck happy # warning gettid() not implemented #endif - assert(snprintf(name, MAX_THREAD_NAME, "tid=%d", tid) > 0); + assert(snprintf(name, US_MAX_THREAD_NAME, "tid=%d", tid) > 0); #ifdef WITH_PTHREAD_NP } diff --git a/src/libs/tools.h b/src/libs/tools.h index ec59c8b..1c92761 100644 --- a/src/libs/tools.h +++ b/src/libs/tools.h @@ -53,37 +53,37 @@ #define INLINE inline __attribute__((always_inline)) #define UNUSED __attribute__((unused)) -#define A_CALLOC(_dest, _nmemb) assert((_dest = calloc(_nmemb, sizeof(*(_dest))))) -#define A_REALLOC(_dest, _nmemb) assert((_dest = realloc(_dest, _nmemb * sizeof(*(_dest))))) -#define DELETE(_dest, _free) { if (_dest) { _free(_dest); } } -#define MEMSET_ZERO(_obj) memset(&(_obj), 0, sizeof(_obj)) +#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_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)) -#define A_ASPRINTF(_dest, _fmt, ...) assert(asprintf(&(_dest), _fmt, ##__VA_ARGS__) >= 0) +#define US_ASPRINTF(x_dest, x_fmt, ...) assert(asprintf(&(x_dest), (x_fmt), ##__VA_ARGS__) >= 0) -#define ARRAY_LEN(_array) (sizeof(_array) / sizeof(_array[0])) +#define US_ARRAY_LEN(x_array) (sizeof(x_array) / sizeof((x_array)[0])) -INLINE const char *bool_to_string(bool flag) { +INLINE const char *us_bool_to_string(bool flag) { return (flag ? "true" : "false"); } -INLINE size_t align_size(size_t size, size_t to) { +INLINE size_t us_align_size(size_t size, size_t to) { return ((size + (to - 1)) & ~(to - 1)); } -INLINE unsigned min_u(unsigned a, unsigned b) { +INLINE unsigned us_min_u(unsigned a, unsigned b) { return (a < b ? a : b); } -INLINE unsigned max_u(unsigned a, unsigned b) { +INLINE unsigned us_max_u(unsigned a, unsigned b) { return (a > b ? a : b); } -INLINE long long floor_ms(long double now) { +INLINE long long us_floor_ms(long double now) { return (long long)now - (now < (long long)now); // floor() } -INLINE uint32_t triple_u32(uint32_t x) { +INLINE uint32_t us_triple_u32(uint32_t x) { // https://nullprogram.com/blog/2018/07/31/ x ^= x >> 17; x *= UINT32_C(0xED5AD4BB); @@ -95,7 +95,7 @@ INLINE uint32_t triple_u32(uint32_t x) { return x; } -INLINE void get_now(clockid_t clk_id, time_t *sec, long *msec) { +INLINE void us_get_now(clockid_t clk_id, time_t *sec, long *msec) { struct timespec ts; assert(!clock_gettime(clk_id, &ts)); *sec = ts.tv_sec; @@ -108,47 +108,47 @@ INLINE void get_now(clockid_t clk_id, time_t *sec, long *msec) { } #if defined(CLOCK_MONOTONIC_RAW) -# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW +# define _X_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW #elif defined(CLOCK_MONOTONIC_FAST) -# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC_FAST +# define _X_CLOCK_MONOTONIC CLOCK_MONOTONIC_FAST #else -# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC +# define _X_CLOCK_MONOTONIC CLOCK_MONOTONIC #endif -INLINE long double get_now_monotonic(void) { +INLINE long double us_get_now_monotonic(void) { time_t sec; long msec; - get_now(X_CLOCK_MONOTONIC, &sec, &msec); + us_get_now(_X_CLOCK_MONOTONIC, &sec, &msec); return (long double)sec + ((long double)msec) / 1000; } -INLINE uint64_t get_now_monotonic_u64(void) { +INLINE uint64_t us_get_now_monotonic_u64(void) { struct timespec ts; - assert(!clock_gettime(X_CLOCK_MONOTONIC, &ts)); + assert(!clock_gettime(_X_CLOCK_MONOTONIC, &ts)); return (uint64_t)(ts.tv_nsec / 1000) + (uint64_t)ts.tv_sec * 1000000; } -#undef X_CLOCK_MONOTONIC +#undef _X_CLOCK_MONOTONIC -INLINE uint64_t get_now_id(void) { - uint64_t now = get_now_monotonic_u64(); - return (uint64_t)triple_u32(now) | ((uint64_t)triple_u32(now + 12345) << 32); +INLINE uint64_t us_get_now_id(void) { + uint64_t now = us_get_now_monotonic_u64(); + return (uint64_t)us_triple_u32(now) | ((uint64_t)us_triple_u32(now + 12345) << 32); } -INLINE long double get_now_real(void) { +INLINE long double us_get_now_real(void) { time_t sec; long msec; - get_now(CLOCK_REALTIME, &sec, &msec); + us_get_now(CLOCK_REALTIME, &sec, &msec); return (long double)sec + ((long double)msec) / 1000; } -INLINE unsigned get_cores_available(void) { +INLINE unsigned us_get_cores_available(void) { long cores_sysconf = sysconf(_SC_NPROCESSORS_ONLN); cores_sysconf = (cores_sysconf < 0 ? 0 : cores_sysconf); - return max_u(min_u(cores_sysconf, 4), 1); + return us_max_u(us_min_u(cores_sysconf, 4), 1); } -INLINE void ld_to_timespec(long double ld, struct timespec *ts) { +INLINE void us_ld_to_timespec(long double ld, struct timespec *ts) { ts->tv_sec = (long)ld; ts->tv_nsec = (ld - ts->tv_sec) * 1000000000L; if (ts->tv_nsec > 999999999L) { @@ -157,17 +157,17 @@ INLINE void ld_to_timespec(long double ld, struct timespec *ts) { } } -INLINE long double timespec_to_ld(const struct timespec *ts) { +INLINE long double us_timespec_to_ld(const struct timespec *ts) { return ts->tv_sec + ((long double)ts->tv_nsec) / 1000000000; } -INLINE int flock_timedwait_monotonic(int fd, long double timeout) { - long double deadline_ts = get_now_monotonic() + timeout; +INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) { + long double deadline_ts = us_get_now_monotonic() + timeout; int retval = -1; while (true) { retval = flock(fd, LOCK_EX | LOCK_NB); - if (retval == 0 || errno != EWOULDBLOCK || get_now_monotonic() > deadline_ts) { + if (retval == 0 || errno != EWOULDBLOCK || us_get_now_monotonic() > deadline_ts) { break; } if (usleep(1000) < 0) { @@ -177,7 +177,7 @@ INLINE int flock_timedwait_monotonic(int fd, long double timeout) { return retval; } -INLINE char *errno_to_string(int error, char *buf, size_t size) { +INLINE char *us_errno_to_string(int error, char *buf, size_t size) { assert(buf); assert(size > 0); locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL); diff --git a/src/libs/unjpeg.c b/src/libs/unjpeg.c index 3a37dd9..9cd7fad 100644 --- a/src/libs/unjpeg.c +++ b/src/libs/unjpeg.c @@ -26,15 +26,15 @@ typedef struct { struct jpeg_error_mgr mgr; // Default manager jmp_buf jmp; - const frame_s *frame; + const us_frame_s *frame; } _jpeg_error_manager_s; static void _jpeg_error_handler(j_common_ptr jpeg); -int unjpeg(const frame_s *src, frame_s *dest, bool decode) { - assert(is_jpeg(src->format)); +int us_unjpeg(const us_frame_s *src, us_frame_s *dest, bool decode) { + assert(us_is_jpeg(src->format)); volatile int retval = 0; @@ -57,7 +57,7 @@ int unjpeg(const frame_s *src, frame_s *dest, bool decode) { jpeg_start_decompress(&jpeg); - frame_copy_meta(src, dest); + us_frame_copy_meta(src, dest); dest->format = V4L2_PIX_FMT_RGB24; dest->width = jpeg.output_width; dest->height = jpeg.output_height; @@ -68,10 +68,10 @@ int unjpeg(const frame_s *src, frame_s *dest, bool decode) { JSAMPARRAY scanlines; scanlines = (*jpeg.mem->alloc_sarray)((j_common_ptr) &jpeg, JPOOL_IMAGE, dest->stride, 1); - frame_realloc_data(dest, ((dest->width * dest->height) << 1) * 2); + us_frame_realloc_data(dest, ((dest->width * dest->height) << 1) * 2); while (jpeg.output_scanline < jpeg.output_height) { jpeg_read_scanlines(&jpeg, scanlines, 1); - frame_append_data(dest, scanlines[0], dest->stride); + us_frame_append_data(dest, scanlines[0], dest->stride); } jpeg_finish_decompress(&jpeg); @@ -87,6 +87,6 @@ static void _jpeg_error_handler(j_common_ptr jpeg) { char msg[JMSG_LENGTH_MAX]; (*jpeg_error->mgr.format_message)(jpeg, msg); - LOG_ERROR("Can't decompress JPEG: %s", msg); + US_LOG_ERROR("Can't decompress JPEG: %s", msg); longjmp(jpeg_error->jmp, -1); } diff --git a/src/libs/unjpeg.h b/src/libs/unjpeg.h index 0696516..90c8df5 100644 --- a/src/libs/unjpeg.h +++ b/src/libs/unjpeg.h @@ -37,4 +37,4 @@ #include "frame.h" -int unjpeg(const frame_s *src, frame_s *dest, bool decode); +int us_unjpeg(const us_frame_s *src, us_frame_s *dest, bool decode); diff --git a/src/libs/xioctl.h b/src/libs/xioctl.h index 07b17e1..b9691a6 100644 --- a/src/libs/xioctl.h +++ b/src/libs/xioctl.h @@ -26,17 +26,15 @@ #include -#include "tools.h" - -#ifndef CFG_XIOCTL_RETRIES -# define CFG_XIOCTL_RETRIES 4 +#ifndef US_CFG_XIOCTL_RETRIES +# define US_CFG_XIOCTL_RETRIES 4 #endif -#define XIOCTL_RETRIES ((unsigned)(CFG_XIOCTL_RETRIES)) +#define _XIOCTL_RETRIES ((unsigned)(US_CFG_XIOCTL_RETRIES)) -INLINE int xioctl(int fd, int request, void *arg) { - int retries = XIOCTL_RETRIES; +INLINE int us_xioctl(int fd, int request, void *arg) { + int retries = _XIOCTL_RETRIES; int retval = -1; do { diff --git a/src/ustreamer/blank.c b/src/ustreamer/blank.c index d91d593..1d3e4b2 100644 --- a/src/ustreamer/blank.c +++ b/src/ustreamer/blank.c @@ -23,50 +23,50 @@ #include "blank.h" -static frame_s *_init_internal(void); -static frame_s *_init_external(const char *path); +static us_frame_s *_init_internal(void); +static us_frame_s *_init_external(const char *path); -frame_s *blank_frame_init(const char *path) { - frame_s *blank = NULL; +us_frame_s *us_blank_frame_init(const char *path) { + us_frame_s *blank = NULL; if (path && path[0] != '\0') { blank = _init_external(path); } if (blank) { - LOG_INFO("Using external blank placeholder: %s", path); + US_LOG_INFO("Using external blank placeholder: %s", path); } else { blank = _init_internal(); - LOG_INFO("Using internal blank placeholder"); + US_LOG_INFO("Using internal blank placeholder"); } return blank; } -static frame_s *_init_internal(void) { - frame_s *blank = frame_init(); - frame_set_data(blank, BLANK_JPEG_DATA, BLANK_JPEG_DATA_SIZE); - blank->width = BLANK_JPEG_WIDTH; - blank->height = BLANK_JPEG_HEIGHT; +static us_frame_s *_init_internal(void) { + us_frame_s *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; blank->format = V4L2_PIX_FMT_JPEG; return blank; } -static frame_s *_init_external(const char *path) { +static us_frame_s *_init_external(const char *path) { FILE *fp = NULL; - frame_s *blank = frame_init(); + us_frame_s *blank = us_frame_init(); blank->format = V4L2_PIX_FMT_JPEG; if ((fp = fopen(path, "rb")) == NULL) { - LOG_PERROR("Can't open blank placeholder '%s'", path); + US_LOG_PERROR("Can't open blank placeholder '%s'", path); goto error; } # define CHUNK_SIZE ((size_t)(100 * 1024)) while (true) { if (blank->used + CHUNK_SIZE >= blank->allocated) { - frame_realloc_data(blank, blank->used + CHUNK_SIZE * 2); + us_frame_realloc_data(blank, blank->used + CHUNK_SIZE * 2); } size_t readed = fread(blank->data + blank->used, 1, CHUNK_SIZE, fp); @@ -76,26 +76,26 @@ static frame_s *_init_external(const char *path) { if (feof(fp)) { break; } else { - LOG_PERROR("Can't read blank placeholder"); + US_LOG_PERROR("Can't read blank placeholder"); goto error; } } } # undef CHUNK_SIZE - frame_s *decoded = frame_init(); - if (unjpeg(blank, decoded, false) < 0) { - frame_destroy(decoded); + us_frame_s *decoded = us_frame_init(); + if (us_unjpeg(blank, decoded, false) < 0) { + us_frame_destroy(decoded); goto error; } blank->width = decoded->width; blank->height = decoded->height; - frame_destroy(decoded); + us_frame_destroy(decoded); goto ok; error: - frame_destroy(blank); + us_frame_destroy(blank); blank = NULL; ok: diff --git a/src/ustreamer/blank.h b/src/ustreamer/blank.h index 0fbb035..74e80fb 100644 --- a/src/ustreamer/blank.h +++ b/src/ustreamer/blank.h @@ -35,4 +35,4 @@ #include "data/blank_jpeg.h" -frame_s *blank_frame_init(const char *path); +us_frame_s *us_blank_frame_init(const char *path); diff --git a/src/ustreamer/data/blank_jpeg.c b/src/ustreamer/data/blank_jpeg.c index c4aaf5e..9ebb2cc 100644 --- a/src/ustreamer/data/blank_jpeg.c +++ b/src/ustreamer/data/blank_jpeg.c @@ -22,11 +22,11 @@ #include "blank_jpeg.h" -const unsigned BLANK_JPEG_WIDTH = 640; -const unsigned BLANK_JPEG_HEIGHT = 480; +const unsigned US_BLANK_JPEG_WIDTH = 640; +const unsigned US_BLANK_JPEG_HEIGHT = 480; -const size_t BLANK_JPEG_DATA_SIZE = 13845; -const uint8_t BLANK_JPEG_DATA[] = { +const size_t US_BLANK_JPEG_DATA_SIZE = 13845; +const uint8_t US_BLANK_JPEG_DATA[] = { 0xFF, 0xD8, 0xFF, 0xE1, 0x09, 0x50, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x78, 0x61, 0x70, 0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x00, 0x3C, 0x3F, 0x78, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6E, 0x3D, 0x22, 0xEF, 0xBB, 0xBF, 0x22, 0x20, 0x69, 0x64, 0x3D, diff --git a/src/ustreamer/data/blank_jpeg.h b/src/ustreamer/data/blank_jpeg.h index 2babf84..26744eb 100644 --- a/src/ustreamer/data/blank_jpeg.h +++ b/src/ustreamer/data/blank_jpeg.h @@ -27,8 +27,8 @@ #include -extern const unsigned BLANK_JPEG_WIDTH; -extern const unsigned BLANK_JPEG_HEIGHT; +extern const unsigned US_BLANK_JPEG_WIDTH; +extern const unsigned US_BLANK_JPEG_HEIGHT; -extern const size_t BLANK_JPEG_DATA_SIZE; -extern const uint8_t BLANK_JPEG_DATA[]; +extern const size_t US_BLANK_JPEG_DATA_SIZE; +extern const uint8_t US_BLANK_JPEG_DATA[]; diff --git a/src/ustreamer/data/index_html.c b/src/ustreamer/data/index_html.c index cdb4d38..9c65b58 100644 --- a/src/ustreamer/data/index_html.c +++ b/src/ustreamer/data/index_html.c @@ -22,7 +22,7 @@ #include "index_html.h" -const char *const HTML_INDEX_PAGE = " \ +const char *const US_HTML_INDEX_PAGE = " \ \ \ \ @@ -33,7 +33,7 @@ const char *const HTML_INDEX_PAGE = " \ \ \ \ -

µStreamer v" VERSION "

\ +

µStreamer v" US_VERSION "

\
\
    \
  • \ diff --git a/src/ustreamer/data/index_html.h b/src/ustreamer/data/index_html.h index f2e976e..99dbe5a 100644 --- a/src/ustreamer/data/index_html.h +++ b/src/ustreamer/data/index_html.h @@ -27,4 +27,4 @@ #include "../../libs/const.h" -extern const char *const HTML_INDEX_PAGE; +extern const char *const US_HTML_INDEX_PAGE; diff --git a/src/ustreamer/device.c b/src/ustreamer/device.c index d2910e3..1372246 100644 --- a/src/ustreamer/device.c +++ b/src/ustreamer/device.c @@ -54,24 +54,24 @@ static const struct { }; -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, bool first); -static void _device_open_hw_fps(device_s *dev); -static void _device_open_jpeg_quality(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 int _device_open_check_cap(us_device_s *dev); +static int _device_open_dv_timings(us_device_s *dev); +static int _device_apply_dv_timings(us_device_s *dev); +static int _device_open_format(us_device_s *dev, bool first); +static void _device_open_hw_fps(us_device_s *dev); +static void _device_open_jpeg_quality(us_device_s *dev); +static int _device_open_io_method(us_device_s *dev); +static int _device_open_io_method_mmap(us_device_s *dev); +static int _device_open_io_method_userptr(us_device_s *dev); +static int _device_open_queue_buffers(us_device_s *dev); +static int _device_apply_resolution(us_device_s *dev, unsigned width, unsigned height); -static void _device_apply_controls(device_s *dev); +static void _device_apply_controls(us_device_s *dev); static int _device_query_control( - device_s *dev, struct v4l2_queryctrl *query, + us_device_s *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, bool quiet); static void _device_set_control( - device_s *dev, struct v4l2_queryctrl *query, + us_device_s *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, int value, bool quiet); static const char *_format_to_string_nullable(unsigned format); @@ -80,17 +80,17 @@ static const char *_standard_to_string(v4l2_std_id standard); static const char *_io_method_to_string_supported(enum v4l2_memory io_method); -#define RUN(_next) dev->run->_next -#define D_XIOCTL(...) xioctl(RUN(fd), __VA_ARGS__) +#define _RUN(x_next) dev->run->x_next +#define _D_XIOCTL(...) us_xioctl(_RUN(fd), __VA_ARGS__) -device_s *device_init(void) { - device_runtime_s *run; - A_CALLOC(run, 1); +us_device_s *us_device_init(void) { + us_device_runtime_s *run; + US_CALLOC(run, 1); run->fd = -1; - device_s *dev; - A_CALLOC(dev, 1); + us_device_s *dev; + US_CALLOC(dev, 1); dev->path = "/dev/video0"; dev->width = 640; dev->height = 480; @@ -98,51 +98,51 @@ device_s *device_init(void) { dev->jpeg_quality = 80; dev->standard = V4L2_STD_UNKNOWN; dev->io_method = V4L2_MEMORY_MMAP; - dev->n_bufs = get_cores_available() + 1; + dev->n_bufs = us_get_cores_available() + 1; dev->min_frame_size = 128; dev->timeout = 1; dev->run = run; return dev; } -void device_destroy(device_s *dev) { +void us_device_destroy(us_device_s *dev) { free(dev->run); free(dev); } -int device_parse_format(const char *str) { - for (unsigned index = 0; index < ARRAY_LEN(_FORMATS); ++index) { +int us_device_parse_format(const char *str) { + for (unsigned index = 0; index < US_ARRAY_LEN(_FORMATS); ++index) { if (!strcasecmp(str, _FORMATS[index].name)) { return _FORMATS[index].format; } } - return FORMAT_UNKNOWN; + return US_FORMAT_UNKNOWN; } -v4l2_std_id device_parse_standard(const char *str) { - for (unsigned index = 1; index < ARRAY_LEN(_STANDARDS); ++index) { +v4l2_std_id us_device_parse_standard(const char *str) { + for (unsigned index = 1; index < US_ARRAY_LEN(_STANDARDS); ++index) { if (!strcasecmp(str, _STANDARDS[index].name)) { return _STANDARDS[index].standard; } } - return STANDARD_UNKNOWN; + return US_STANDARD_UNKNOWN; } -int device_parse_io_method(const char *str) { - for (unsigned index = 0; index < ARRAY_LEN(_IO_METHODS); ++index) { +int us_device_parse_io_method(const char *str) { + for (unsigned index = 0; index < US_ARRAY_LEN(_IO_METHODS); ++index) { if (!strcasecmp(str, _IO_METHODS[index].name)) { return _IO_METHODS[index].io_method; } } - return IO_METHOD_UNKNOWN; + return US_IO_METHOD_UNKNOWN; } -int device_open(device_s *dev) { - if ((RUN(fd) = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) { - LOG_PERROR("Can't open device"); +int us_device_open(us_device_s *dev) { + if ((_RUN(fd) = open(dev->path, O_RDWR|O_NONBLOCK)) < 0) { + US_LOG_PERROR("Can't open device"); goto error; } - LOG_INFO("Device fd=%d opened", RUN(fd)); + US_LOG_INFO("Device fd=%d opened", _RUN(fd)); if (_device_open_check_cap(dev) < 0) { goto error; @@ -163,21 +163,21 @@ int device_open(device_s *dev) { } _device_apply_controls(dev); - LOG_DEBUG("Device fd=%d initialized", RUN(fd)); + US_LOG_DEBUG("Device fd=%d initialized", _RUN(fd)); return 0; error: - device_close(dev); + us_device_close(dev); return -1; } -void device_close(device_s *dev) { - RUN(persistent_timeout_reported) = false; +void us_device_close(us_device_s *dev) { + _RUN(persistent_timeout_reported) = false; - if (RUN(hw_bufs)) { - LOG_DEBUG("Releasing device buffers ..."); - for (unsigned index = 0; index < RUN(n_bufs); ++index) { -# define HW(_next) RUN(hw_bufs)[index]._next + if (_RUN(hw_bufs)) { + 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 if (HW(dma_fd) >= 0) { close(HW(dma_fd)); @@ -187,7 +187,7 @@ void device_close(device_s *dev) { if (dev->io_method == V4L2_MEMORY_MMAP) { if (HW(raw.allocated) > 0 && HW(raw.data) != MAP_FAILED) { if (munmap(HW(raw.data), HW(raw.allocated)) < 0) { - LOG_PERROR("Can't unmap device buffer=%u", index); + US_LOG_PERROR("Can't unmap device buffer=%u", index); } } } else { // V4L2_MEMORY_USERPTR @@ -198,33 +198,33 @@ void device_close(device_s *dev) { # undef HW } - RUN(n_bufs) = 0; - free(RUN(hw_bufs)); - RUN(hw_bufs) = NULL; + _RUN(n_bufs) = 0; + free(_RUN(hw_bufs)); + _RUN(hw_bufs) = NULL; } - if (RUN(fd) >= 0) { - LOG_DEBUG("Closing device ..."); - if (close(RUN(fd)) < 0) { - LOG_PERROR("Can't close device fd=%d", RUN(fd)); + if (_RUN(fd) >= 0) { + US_LOG_DEBUG("Closing device ..."); + if (close(_RUN(fd)) < 0) { + US_LOG_PERROR("Can't close device fd=%d", _RUN(fd)); } else { - LOG_INFO("Device fd=%d closed", RUN(fd)); + US_LOG_INFO("Device fd=%d closed", _RUN(fd)); } - RUN(fd) = -1; + _RUN(fd) = -1; } } -int device_export_to_dma(device_s *dev) { -# define DMA_FD RUN(hw_bufs[index].dma_fd) +int us_device_export_to_dma(us_device_s *dev) { +# define DMA_FD _RUN(hw_bufs[index].dma_fd) - for (unsigned index = 0; index < RUN(n_bufs); ++index) { + for (unsigned index = 0; index < _RUN(n_bufs); ++index) { struct v4l2_exportbuffer exp = {0}; exp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; exp.index = index; - LOG_DEBUG("Exporting device buffer=%u to DMA ...", index); - if (D_XIOCTL(VIDIOC_EXPBUF, &exp) < 0) { - LOG_PERROR("Can't export device buffer=%u to DMA", index); + US_LOG_DEBUG("Exporting device buffer=%u to DMA ...", index); + if (_D_XIOCTL(VIDIOC_EXPBUF, &exp) < 0) { + US_LOG_PERROR("Can't export device buffer=%u to DMA", index); goto error; } DMA_FD = exp.fd; @@ -233,7 +233,7 @@ int device_export_to_dma(device_s *dev) { return 0; error: - for (unsigned index = 0; index < RUN(n_bufs); ++index) { + for (unsigned index = 0; index < _RUN(n_bufs); ++index) { if (DMA_FD >= 0) { close(DMA_FD); DMA_FD = -1; @@ -244,29 +244,29 @@ int device_export_to_dma(device_s *dev) { # undef DMA_FD } -int device_switch_capturing(device_s *dev, bool enable) { - if (enable != RUN(capturing)) { +int us_device_switch_capturing(us_device_s *dev, bool enable) { + if (enable != _RUN(capturing)) { enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - LOG_DEBUG("%s device capturing ...", (enable ? "Starting" : "Stopping")); - if (D_XIOCTL((enable ? VIDIOC_STREAMON : VIDIOC_STREAMOFF), &type) < 0) { - LOG_PERROR("Can't %s capturing", (enable ? "start" : "stop")); + US_LOG_DEBUG("%s device capturing ...", (enable ? "Starting" : "Stopping")); + if (_D_XIOCTL((enable ? VIDIOC_STREAMON : VIDIOC_STREAMOFF), &type) < 0) { + US_LOG_PERROR("Can't %s capturing", (enable ? "start" : "stop")); if (enable) { return -1; } } - RUN(capturing) = enable; - LOG_INFO("Capturing %s", (enable ? "started" : "stopped")); + _RUN(capturing) = enable; + US_LOG_INFO("Capturing %s", (enable ? "started" : "stopped")); } return 0; } -int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_error) { +int us_device_select(us_device_s *dev, bool *has_read, bool *has_write, bool *has_error) { int retval; -# define INIT_FD_SET(_set) \ - fd_set _set; FD_ZERO(&_set); FD_SET(RUN(fd), &_set); +# define INIT_FD_SET(x_set) \ + fd_set x_set; FD_ZERO(&x_set); FD_SET(_RUN(fd), &x_set); INIT_FD_SET(read_fds); INIT_FD_SET(write_fds); @@ -278,27 +278,27 @@ int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_erro timeout.tv_sec = dev->timeout; timeout.tv_usec = 0; - LOG_DEBUG("Calling select() on video device ..."); + US_LOG_DEBUG("Calling select() on video device ..."); - retval = select(RUN(fd) + 1, &read_fds, &write_fds, &error_fds, &timeout); + retval = select(_RUN(fd) + 1, &read_fds, &write_fds, &error_fds, &timeout); if (retval > 0) { - *has_read = FD_ISSET(RUN(fd), &read_fds); - *has_write = FD_ISSET(RUN(fd), &write_fds); - *has_error = FD_ISSET(RUN(fd), &error_fds); + *has_read = FD_ISSET(_RUN(fd), &read_fds); + *has_write = FD_ISSET(_RUN(fd), &write_fds); + *has_error = FD_ISSET(_RUN(fd), &error_fds); } else { *has_read = false; *has_write = false; *has_error = false; } - LOG_DEBUG("Device select() --> %d", retval); + US_LOG_DEBUG("Device select() --> %d", retval); if (retval > 0) { - RUN(persistent_timeout_reported) = false; + _RUN(persistent_timeout_reported) = false; } else if (retval == 0) { if (dev->persistent) { - if (!RUN(persistent_timeout_reported)) { - LOG_ERROR("Persistent device timeout (unplugged)"); - RUN(persistent_timeout_reported) = true; + if (!_RUN(persistent_timeout_reported)) { + US_LOG_ERROR("Persistent device timeout (unplugged)"); + _RUN(persistent_timeout_reported) = true; } } else { // Если устройство не персистентное, то таймаут является ошибкой @@ -308,23 +308,23 @@ int device_select(device_s *dev, bool *has_read, bool *has_write, bool *has_erro return retval; } -int device_grab_buffer(device_s *dev, hw_buffer_s **hw) { +int us_device_grab_buffer(us_device_s *dev, us_hw_buffer_s **hw) { *hw = NULL; struct v4l2_buffer buf = {0}; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = dev->io_method; - LOG_DEBUG("Grabbing device buffer ..."); - if (D_XIOCTL(VIDIOC_DQBUF, &buf) < 0) { - LOG_PERROR("Can't grab device buffer"); + US_LOG_DEBUG("Grabbing device buffer ..."); + if (_D_XIOCTL(VIDIOC_DQBUF, &buf) < 0) { + US_LOG_PERROR("Can't grab device buffer"); return -1; } - LOG_DEBUG("Grabbed new frame: buffer=%u, bytesused=%u", buf.index, buf.bytesused); + US_LOG_DEBUG("Grabbed new frame: buffer=%u, bytesused=%u", buf.index, buf.bytesused); - if (buf.index >= RUN(n_bufs)) { - LOG_ERROR("V4L2 error: grabbed invalid device buffer=%u, n_bufs=%u", buf.index, RUN(n_bufs)); + if (buf.index >= _RUN(n_bufs)) { + US_LOG_ERROR("V4L2 error: grabbed invalid device buffer=%u, n_bufs=%u", buf.index, _RUN(n_bufs)); return -1; } @@ -334,112 +334,112 @@ int device_grab_buffer(device_s *dev, hw_buffer_s **hw) { // For example a VGA (640x480) webcam frame is normally >= 8kByte large, // corrupted frames are smaller. if (buf.bytesused < dev->min_frame_size) { - LOG_DEBUG("Dropped too small frame, assuming it was broken: buffer=%u, bytesused=%u", + US_LOG_DEBUG("Dropped too small frame, assuming it was broken: buffer=%u, bytesused=%u", buf.index, buf.bytesused); - LOG_DEBUG("Releasing device buffer=%u (broken frame) ...", buf.index); - if (D_XIOCTL(VIDIOC_QBUF, &buf) < 0) { - LOG_PERROR("Can't release device buffer=%u (broken frame)", buf.index); + US_LOG_DEBUG("Releasing device buffer=%u (broken frame) ...", buf.index); + if (_D_XIOCTL(VIDIOC_QBUF, &buf) < 0) { + US_LOG_PERROR("Can't release device buffer=%u (broken frame)", buf.index); return -1; } return -2; } -# define HW(_next) RUN(hw_bufs)[buf.index]._next +# define HW(x_next) _RUN(hw_bufs)[buf.index].x_next if (HW(grabbed)) { - LOG_ERROR("V4L2 error: grabbed device buffer=%u is already used", buf.index); + US_LOG_ERROR("V4L2 error: grabbed device buffer=%u is already used", buf.index); return -1; } HW(grabbed) = true; HW(raw.dma_fd) = HW(dma_fd); HW(raw.used) = buf.bytesused; - HW(raw.width) = RUN(width); - HW(raw.height) = RUN(height); - HW(raw.format) = RUN(format); - HW(raw.stride) = RUN(stride); + HW(raw.width) = _RUN(width); + HW(raw.height) = _RUN(height); + HW(raw.format) = _RUN(format); + HW(raw.stride) = _RUN(stride); HW(raw.online) = true; memcpy(&HW(buf), &buf, sizeof(struct v4l2_buffer)); - HW(raw.grab_ts) = get_now_monotonic(); + HW(raw.grab_ts) = us_get_now_monotonic(); # undef HW - *hw = &RUN(hw_bufs[buf.index]); + *hw = &_RUN(hw_bufs[buf.index]); return buf.index; } -int device_release_buffer(device_s *dev, hw_buffer_s *hw) { +int us_device_release_buffer(us_device_s *dev, us_hw_buffer_s *hw) { const unsigned index = hw->buf.index; - LOG_DEBUG("Releasing device buffer=%u ...", index); + US_LOG_DEBUG("Releasing device buffer=%u ...", index); - if (D_XIOCTL(VIDIOC_QBUF, &hw->buf) < 0) { - LOG_PERROR("Can't release device buffer=%u", index); + if (_D_XIOCTL(VIDIOC_QBUF, &hw->buf) < 0) { + US_LOG_PERROR("Can't release device buffer=%u", index); return -1; } hw->grabbed = false; return 0; } -int device_consume_event(device_s *dev) { +int us_device_consume_event(us_device_s *dev) { struct v4l2_event event; - LOG_DEBUG("Consuming V4L2 event ..."); - if (D_XIOCTL(VIDIOC_DQEVENT, &event) == 0) { + US_LOG_DEBUG("Consuming V4L2 event ..."); + if (_D_XIOCTL(VIDIOC_DQEVENT, &event) == 0) { switch (event.type) { case V4L2_EVENT_SOURCE_CHANGE: - LOG_INFO("Got V4L2_EVENT_SOURCE_CHANGE: source changed"); + US_LOG_INFO("Got V4L2_EVENT_SOURCE_CHANGE: source changed"); return -1; case V4L2_EVENT_EOS: - LOG_INFO("Got V4L2_EVENT_EOS: end of stream (ignored)"); + US_LOG_INFO("Got V4L2_EVENT_EOS: end of stream (ignored)"); return 0; } } else { - LOG_PERROR("Got some V4L2 device event, but where is it? "); + US_LOG_PERROR("Got some V4L2 device event, but where is it? "); } return 0; } -static int _device_open_check_cap(device_s *dev) { +static int _device_open_check_cap(us_device_s *dev) { struct v4l2_capability cap = {0}; - LOG_DEBUG("Querying device capabilities ..."); - if (D_XIOCTL(VIDIOC_QUERYCAP, &cap) < 0) { - LOG_PERROR("Can't query device capabilities"); + US_LOG_DEBUG("Querying device capabilities ..."); + if (_D_XIOCTL(VIDIOC_QUERYCAP, &cap) < 0) { + US_LOG_PERROR("Can't query device capabilities"); return -1; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { - LOG_ERROR("Video capture is not supported by device"); + US_LOG_ERROR("Video capture is not supported by device"); return -1; } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { - LOG_ERROR("Device doesn't support streaming IO"); + US_LOG_ERROR("Device doesn't support streaming IO"); return -1; } int input = dev->input; // Needs a pointer to int for ioctl() - LOG_INFO("Using input channel: %d", input); - if (D_XIOCTL(VIDIOC_S_INPUT, &input) < 0) { - LOG_ERROR("Can't set input channel"); + US_LOG_INFO("Using input channel: %d", input); + if (_D_XIOCTL(VIDIOC_S_INPUT, &input) < 0) { + US_LOG_ERROR("Can't set input channel"); return -1; } if (dev->standard != V4L2_STD_UNKNOWN) { - LOG_INFO("Using TV standard: %s", _standard_to_string(dev->standard)); - if (D_XIOCTL(VIDIOC_S_STD, &dev->standard) < 0) { - LOG_ERROR("Can't set video standard"); + US_LOG_INFO("Using TV standard: %s", _standard_to_string(dev->standard)); + if (_D_XIOCTL(VIDIOC_S_STD, &dev->standard) < 0) { + US_LOG_ERROR("Can't set video standard"); return -1; } } else { - LOG_DEBUG("Using TV standard: DEFAULT"); + US_LOG_DEBUG("Using TV standard: DEFAULT"); } return 0; } -static int _device_open_dv_timings(device_s *dev) { +static int _device_open_dv_timings(us_device_s *dev) { _device_apply_resolution(dev, dev->width, dev->height); if (dev->dv_timings) { - LOG_DEBUG("Using DV-timings"); + US_LOG_DEBUG("Using DV-timings"); if (_device_apply_dv_timings(dev) < 0) { return -1; @@ -448,20 +448,20 @@ static int _device_open_dv_timings(device_s *dev) { struct v4l2_event_subscription sub = {0}; sub.type = V4L2_EVENT_SOURCE_CHANGE; - LOG_DEBUG("Subscribing to DV-timings events ...") - if (D_XIOCTL(VIDIOC_SUBSCRIBE_EVENT, &sub) < 0) { - LOG_PERROR("Can't subscribe to DV-timings events"); + US_LOG_DEBUG("Subscribing to DV-timings events ...") + if (_D_XIOCTL(VIDIOC_SUBSCRIBE_EVENT, &sub) < 0) { + US_LOG_PERROR("Can't subscribe to DV-timings events"); return -1; } } return 0; } -static int _device_apply_dv_timings(device_s *dev) { +static int _device_apply_dv_timings(us_device_s *dev) { struct v4l2_dv_timings dv = {0}; - LOG_DEBUG("Calling xioctl(VIDIOC_QUERY_DV_TIMINGS) ..."); - if (D_XIOCTL(VIDIOC_QUERY_DV_TIMINGS, &dv) == 0) { + US_LOG_DEBUG("Calling us_xioctl(VIDIOC_QUERY_DV_TIMINGS) ..."); + 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); @@ -470,18 +470,18 @@ static int _device_apply_dv_timings(device_s *dev) { vtot /= 2; } unsigned fps = ((htot * vtot) > 0 ? ((100 * (uint64_t)dv.bt.pixelclock)) / (htot * vtot) : 0); - LOG_INFO("Got new DV-timings: %ux%u%s%u.%02u, pixclk=%llu, vsync=%u, hsync=%u", + 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 } else { - LOG_INFO("Got new DV-timings: %ux%u, pixclk=%llu, vsync=%u, hsync=%u", + US_LOG_INFO("Got new DV-timings: %ux%u, pixclk=%llu, vsync=%u, hsync=%u", dv.bt.width, dv.bt.height, (unsigned long long)dv.bt.pixelclock, dv.bt.vsync, dv.bt.hsync); } - LOG_DEBUG("Calling xioctl(VIDIOC_S_DV_TIMINGS) ..."); - if (D_XIOCTL(VIDIOC_S_DV_TIMINGS, &dv) < 0) { - LOG_PERROR("Failed to set DV-timings"); + US_LOG_DEBUG("Calling us_xioctl(VIDIOC_S_DV_TIMINGS) ..."); + if (_D_XIOCTL(VIDIOC_S_DV_TIMINGS, &dv) < 0) { + US_LOG_PERROR("Failed to set DV-timings"); return -1; } @@ -490,11 +490,11 @@ static int _device_apply_dv_timings(device_s *dev) { } } else { - LOG_DEBUG("Calling xioctl(VIDIOC_QUERYSTD) ..."); - if (D_XIOCTL(VIDIOC_QUERYSTD, &dev->standard) == 0) { - LOG_INFO("Applying the new VIDIOC_S_STD: %s ...", _standard_to_string(dev->standard)); - if (D_XIOCTL(VIDIOC_S_STD, &dev->standard) < 0) { - LOG_PERROR("Can't set video standard"); + US_LOG_DEBUG("Calling us_xioctl(VIDIOC_QUERYSTD) ..."); + if (_D_XIOCTL(VIDIOC_QUERYSTD, &dev->standard) == 0) { + US_LOG_INFO("Applying the new VIDIOC_S_STD: %s ...", _standard_to_string(dev->standard)); + if (_D_XIOCTL(VIDIOC_S_STD, &dev->standard) < 0) { + US_LOG_PERROR("Can't set video standard"); return -1; } } @@ -502,29 +502,29 @@ static int _device_apply_dv_timings(device_s *dev) { return 0; } -static int _device_open_format(device_s *dev, bool first) { - const unsigned stride = align_size(RUN(width), 32) << 1; +static int _device_open_format(us_device_s *dev, bool first) { + const unsigned stride = us_align_size(_RUN(width), 32) << 1; struct v4l2_format fmt = {0}; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = RUN(width); - fmt.fmt.pix.height = RUN(height); + fmt.fmt.pix.width = _RUN(width); + fmt.fmt.pix.height = _RUN(height); fmt.fmt.pix.pixelformat = dev->format; fmt.fmt.pix.field = V4L2_FIELD_ANY; fmt.fmt.pix.bytesperline = stride; // Set format - LOG_DEBUG("Probing device format=%s, stride=%u, resolution=%ux%u ...", - _format_to_string_supported(dev->format), stride, RUN(width), RUN(height)); - if (D_XIOCTL(VIDIOC_S_FMT, &fmt) < 0) { - LOG_PERROR("Can't set device format"); + US_LOG_DEBUG("Probing device format=%s, stride=%u, resolution=%ux%u ...", + _format_to_string_supported(dev->format), stride, _RUN(width), _RUN(height)); + if (_D_XIOCTL(VIDIOC_S_FMT, &fmt) < 0) { + US_LOG_PERROR("Can't set device format"); return -1; } // Check resolution bool retry = false; - if (fmt.fmt.pix.width != RUN(width) || fmt.fmt.pix.height != RUN(height)) { - LOG_ERROR("Requested resolution=%ux%u is unavailable", RUN(width), RUN(height)); + if (fmt.fmt.pix.width != _RUN(width) || fmt.fmt.pix.height != _RUN(height)) { + US_LOG_ERROR("Requested resolution=%ux%u is unavailable", _RUN(width), _RUN(height)); retry = true; } if (_device_apply_resolution(dev, fmt.fmt.pix.width, fmt.fmt.pix.height) < 0) { @@ -533,109 +533,109 @@ static int _device_open_format(device_s *dev, bool first) { if (first && retry) { return _device_open_format(dev, false); } - LOG_INFO("Using resolution: %ux%u", RUN(width), RUN(height)); + US_LOG_INFO("Using resolution: %ux%u", _RUN(width), _RUN(height)); // Check format if (fmt.fmt.pix.pixelformat != dev->format) { - LOG_ERROR("Could not obtain the requested format=%s; driver gave us %s", + US_LOG_ERROR("Could not obtain the requested format=%s; driver gave us %s", _format_to_string_supported(dev->format), _format_to_string_supported(fmt.fmt.pix.pixelformat)); char *format_str; if ((format_str = (char *)_format_to_string_nullable(fmt.fmt.pix.pixelformat)) != NULL) { - LOG_INFO("Falling back to format=%s", format_str); + US_LOG_INFO("Falling back to format=%s", format_str); } else { char fourcc_str[8]; - LOG_ERROR("Unsupported format=%s (fourcc)", - fourcc_to_string(fmt.fmt.pix.pixelformat, fourcc_str, 8)); + US_LOG_ERROR("Unsupported format=%s (fourcc)", + us_fourcc_to_string(fmt.fmt.pix.pixelformat, fourcc_str, 8)); return -1; } } - RUN(format) = fmt.fmt.pix.pixelformat; - LOG_INFO("Using format: %s", _format_to_string_supported(RUN(format))); + _RUN(format) = fmt.fmt.pix.pixelformat; + US_LOG_INFO("Using format: %s", _format_to_string_supported(_RUN(format))); - RUN(stride) = fmt.fmt.pix.bytesperline; - RUN(raw_size) = fmt.fmt.pix.sizeimage; // Only for userptr + _RUN(stride) = fmt.fmt.pix.bytesperline; + _RUN(raw_size) = fmt.fmt.pix.sizeimage; // Only for userptr return 0; } -static void _device_open_hw_fps(device_s *dev) { - RUN(hw_fps) = 0; +static void _device_open_hw_fps(us_device_s *dev) { + _RUN(hw_fps) = 0; struct v4l2_streamparm setfps = {0}; setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - LOG_DEBUG("Querying HW FPS ..."); - if (D_XIOCTL(VIDIOC_G_PARM, &setfps) < 0) { + US_LOG_DEBUG("Querying HW FPS ..."); + if (_D_XIOCTL(VIDIOC_G_PARM, &setfps) < 0) { if (errno == ENOTTY) { // Quiet message for TC358743 - LOG_INFO("Querying HW FPS changing is not supported"); + US_LOG_INFO("Querying HW FPS changing is not supported"); } else { - LOG_PERROR("Can't query HW FPS changing"); + US_LOG_PERROR("Can't query HW FPS changing"); } return; } if (!(setfps.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) { - LOG_INFO("Changing HW FPS is not supported"); + US_LOG_INFO("Changing HW FPS is not supported"); return; } -# define SETFPS_TPF(_next) setfps.parm.capture.timeperframe._next +# define SETFPS_TPF(x_next) setfps.parm.capture.timeperframe.x_next - MEMSET_ZERO(setfps); + US_MEMSET_ZERO(setfps); setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; SETFPS_TPF(numerator) = 1; SETFPS_TPF(denominator) = (dev->desired_fps == 0 ? 255 : dev->desired_fps); - if (D_XIOCTL(VIDIOC_S_PARM, &setfps) < 0) { - LOG_PERROR("Can't set HW FPS"); + if (_D_XIOCTL(VIDIOC_S_PARM, &setfps) < 0) { + US_LOG_PERROR("Can't set HW FPS"); return; } if (SETFPS_TPF(numerator) != 1) { - LOG_ERROR("Invalid HW FPS numerator: %u != 1", SETFPS_TPF(numerator)); + US_LOG_ERROR("Invalid HW FPS numerator: %u != 1", SETFPS_TPF(numerator)); return; } if (SETFPS_TPF(denominator) == 0) { // Не знаю, бывает ли так, но пускай на всякий случай - LOG_ERROR("Invalid HW FPS denominator: 0"); + US_LOG_ERROR("Invalid HW FPS denominator: 0"); return; } - RUN(hw_fps) = SETFPS_TPF(denominator); - if (dev->desired_fps != RUN(hw_fps)) { - LOG_INFO("Using HW FPS: %u -> %u (coerced)", dev->desired_fps, RUN(hw_fps)); + _RUN(hw_fps) = SETFPS_TPF(denominator); + if (dev->desired_fps != _RUN(hw_fps)) { + US_LOG_INFO("Using HW FPS: %u -> %u (coerced)", dev->desired_fps, _RUN(hw_fps)); } else { - LOG_INFO("Using HW FPS: %u", RUN(hw_fps)); + US_LOG_INFO("Using HW FPS: %u", _RUN(hw_fps)); } # undef SETFPS_TPF } -static void _device_open_jpeg_quality(device_s *dev) { +static void _device_open_jpeg_quality(us_device_s *dev) { unsigned quality = 0; - if (is_jpeg(RUN(format))) { + if (us_is_jpeg(_RUN(format))) { struct v4l2_jpegcompression comp = {0}; - if (D_XIOCTL(VIDIOC_G_JPEGCOMP, &comp) < 0) { - LOG_ERROR("Device doesn't support setting of HW encoding quality parameters"); + if (_D_XIOCTL(VIDIOC_G_JPEGCOMP, &comp) < 0) { + US_LOG_ERROR("Device doesn't support setting of HW encoding quality parameters"); } else { comp.quality = dev->jpeg_quality; - if (D_XIOCTL(VIDIOC_S_JPEGCOMP, &comp) < 0) { - LOG_ERROR("Can't change MJPEG quality for JPEG source with HW pass-through encoder"); + if (_D_XIOCTL(VIDIOC_S_JPEGCOMP, &comp) < 0) { + US_LOG_ERROR("Can't change MJPEG quality for JPEG source with HW pass-through encoder"); } else { quality = dev->jpeg_quality; } } } - RUN(jpeg_quality) = quality; + _RUN(jpeg_quality) = quality; } -static int _device_open_io_method(device_s *dev) { - LOG_INFO("Using IO method: %s", _io_method_to_string_supported(dev->io_method)); +static int _device_open_io_method(us_device_s *dev) { + US_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); case V4L2_MEMORY_USERPTR: return _device_open_io_method_userptr(dev); @@ -644,54 +644,54 @@ static int _device_open_io_method(device_s *dev) { return -1; } -static int _device_open_io_method_mmap(device_s *dev) { +static int _device_open_io_method_mmap(us_device_s *dev) { struct v4l2_requestbuffers req = {0}; req.count = dev->n_bufs; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; - LOG_DEBUG("Requesting %u device buffers for MMAP ...", req.count); - if (D_XIOCTL(VIDIOC_REQBUFS, &req) < 0) { - LOG_PERROR("Device '%s' doesn't support MMAP method", dev->path); + US_LOG_DEBUG("Requesting %u device buffers for MMAP ...", req.count); + if (_D_XIOCTL(VIDIOC_REQBUFS, &req) < 0) { + US_LOG_PERROR("Device '%s' doesn't support MMAP method", dev->path); return -1; } if (req.count < 1) { - LOG_ERROR("Insufficient buffer memory: %u", req.count); + US_LOG_ERROR("Insufficient buffer memory: %u", req.count); return -1; } else { - LOG_INFO("Requested %u device buffers, got %u", dev->n_bufs, req.count); + US_LOG_INFO("Requested %u device buffers, got %u", dev->n_bufs, req.count); } - LOG_DEBUG("Allocating device buffers ..."); + US_LOG_DEBUG("Allocating device buffers ..."); - A_CALLOC(RUN(hw_bufs), req.count); - for (RUN(n_bufs) = 0; RUN(n_bufs) < req.count; ++RUN(n_bufs)) { + US_CALLOC(_RUN(hw_bufs), req.count); + for (_RUN(n_bufs) = 0; _RUN(n_bufs) < req.count; ++_RUN(n_bufs)) { struct v4l2_buffer buf = {0}; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - buf.index = RUN(n_bufs); + buf.index = _RUN(n_bufs); - LOG_DEBUG("Calling xioctl(VIDIOC_QUERYBUF) for device buffer=%u ...", RUN(n_bufs)); - if (D_XIOCTL(VIDIOC_QUERYBUF, &buf) < 0) { - LOG_PERROR("Can't VIDIOC_QUERYBUF"); + US_LOG_DEBUG("Calling us_xioctl(VIDIOC_QUERYBUF) for device buffer=%u ...", _RUN(n_bufs)); + if (_D_XIOCTL(VIDIOC_QUERYBUF, &buf) < 0) { + US_LOG_PERROR("Can't VIDIOC_QUERYBUF"); return -1; } -# define HW(_next) RUN(hw_bufs)[RUN(n_bufs)]._next +# define HW(x_next) _RUN(hw_bufs)[_RUN(n_bufs)].x_next HW(dma_fd) = -1; - LOG_DEBUG("Mapping device buffer=%u ...", RUN(n_bufs)); + US_LOG_DEBUG("Mapping device buffer=%u ...", _RUN(n_bufs)); if ((HW(raw.data) = mmap( NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, - RUN(fd), + _RUN(fd), buf.m.offset )) == MAP_FAILED) { - LOG_PERROR("Can't map device buffer=%u", RUN(n_bufs)); + US_LOG_PERROR("Can't map device buffer=%u", _RUN(n_bufs)); return -1; } HW(raw.allocated) = buf.length; @@ -701,34 +701,34 @@ static int _device_open_io_method_mmap(device_s *dev) { return 0; } -static int _device_open_io_method_userptr(device_s *dev) { +static int _device_open_io_method_userptr(us_device_s *dev) { struct v4l2_requestbuffers req = {0}; req.count = dev->n_bufs; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; - LOG_DEBUG("Requesting %u device buffers for USERPTR ...", req.count); - if (D_XIOCTL(VIDIOC_REQBUFS, &req) < 0) { - LOG_PERROR("Device '%s' doesn't support USERPTR method", dev->path); + US_LOG_DEBUG("Requesting %u device buffers for USERPTR ...", req.count); + if (_D_XIOCTL(VIDIOC_REQBUFS, &req) < 0) { + US_LOG_PERROR("Device '%s' doesn't support USERPTR method", dev->path); return -1; } if (req.count < 1) { - LOG_ERROR("Insufficient buffer memory: %u", req.count); + US_LOG_ERROR("Insufficient buffer memory: %u", req.count); return -1; } else { - LOG_INFO("Requested %u device buffers, got %u", dev->n_bufs, req.count); + US_LOG_INFO("Requested %u device buffers, got %u", dev->n_bufs, req.count); } - LOG_DEBUG("Allocating device buffers ..."); + US_LOG_DEBUG("Allocating device buffers ..."); - A_CALLOC(RUN(hw_bufs), req.count); + US_CALLOC(_RUN(hw_bufs), req.count); const unsigned page_size = getpagesize(); - const unsigned buf_size = align_size(RUN(raw_size), page_size); + const unsigned buf_size = us_align_size(_RUN(raw_size), page_size); - for (RUN(n_bufs) = 0; RUN(n_bufs) < req.count; ++RUN(n_bufs)) { -# define HW(_next) RUN(hw_bufs)[RUN(n_bufs)]._next + 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)); memset(HW(raw.data), 0, buf_size); HW(raw.allocated) = buf_size; @@ -737,75 +737,75 @@ static int _device_open_io_method_userptr(device_s *dev) { return 0; } -static int _device_open_queue_buffers(device_s *dev) { - for (unsigned index = 0; index < RUN(n_bufs); ++index) { +static int _device_open_queue_buffers(us_device_s *dev) { + for (unsigned index = 0; index < _RUN(n_bufs); ++index) { struct v4l2_buffer buf = {0}; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = dev->io_method; buf.index = index; if (dev->io_method == V4L2_MEMORY_USERPTR) { - buf.m.userptr = (unsigned long)RUN(hw_bufs)[index].raw.data; - buf.length = RUN(hw_bufs)[index].raw.allocated; + buf.m.userptr = (unsigned long)_RUN(hw_bufs)[index].raw.data; + buf.length = _RUN(hw_bufs)[index].raw.allocated; } - LOG_DEBUG("Calling xioctl(VIDIOC_QBUF) for buffer=%u ...", index); - if (D_XIOCTL(VIDIOC_QBUF, &buf) < 0) { - LOG_PERROR("Can't VIDIOC_QBUF"); + US_LOG_DEBUG("Calling us_xioctl(VIDIOC_QBUF) for buffer=%u ...", index); + if (_D_XIOCTL(VIDIOC_QBUF, &buf) < 0) { + US_LOG_PERROR("Can't VIDIOC_QBUF"); return -1; } } return 0; } -static int _device_apply_resolution(device_s *dev, unsigned width, unsigned height) { +static int _device_apply_resolution(us_device_s *dev, unsigned width, unsigned height) { // Тут VIDEO_MIN_* не используются из-за странностей минимального разрешения при отсутствии сигнала // у некоторых устройств, например TC358743 if ( - width == 0 || width > VIDEO_MAX_WIDTH - || height == 0 || height > VIDEO_MAX_HEIGHT + width == 0 || width > US_VIDEO_MAX_WIDTH + || height == 0 || height > US_VIDEO_MAX_HEIGHT ) { - LOG_ERROR("Requested forbidden resolution=%ux%u: min=1x1, max=%ux%u", - width, height, VIDEO_MAX_WIDTH, VIDEO_MAX_HEIGHT); + US_LOG_ERROR("Requested forbidden resolution=%ux%u: min=1x1, max=%ux%u", + width, height, US_VIDEO_MAX_WIDTH, US_VIDEO_MAX_HEIGHT); return -1; } - RUN(width) = width; - RUN(height) = height; + _RUN(width) = width; + _RUN(height) = height; return 0; } -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) { \ - _device_set_control(dev, &query, #_field, _cid, _value, _quiet); \ +static void _device_apply_controls(us_device_s *dev) { +# define SET_CID_VALUE(x_cid, x_field, x_value, x_quiet) { \ + struct v4l2_queryctrl m_query; \ + if (_device_query_control(dev, &m_query, #x_field, x_cid, x_quiet) == 0) { \ + _device_set_control(dev, &m_query, #x_field, x_cid, x_value, x_quiet); \ } \ } -# define SET_CID_DEFAULT(_cid, _field, _quiet) { \ - struct v4l2_queryctrl query; \ - if (_device_query_control(dev, &query, #_field, _cid, _quiet) == 0) { \ - _device_set_control(dev, &query, #_field, _cid, query.default_value, _quiet); \ +# define SET_CID_DEFAULT(x_cid, x_field, x_quiet) { \ + struct v4l2_queryctrl m_query; \ + if (_device_query_control(dev, &m_query, #x_field, x_cid, x_quiet) == 0) { \ + _device_set_control(dev, &m_query, #x_field, x_cid, m_query.default_value, x_quiet); \ } \ } -# define CONTROL_MANUAL_CID(_cid, _field) { \ - if (dev->ctl._field.mode == CTL_MODE_VALUE) { \ - SET_CID_VALUE(_cid, _field, dev->ctl._field.value, false); \ - } else if (dev->ctl._field.mode == CTL_MODE_DEFAULT) { \ - SET_CID_DEFAULT(_cid, _field, false); \ +# define CONTROL_MANUAL_CID(x_cid, x_field) { \ + if (dev->ctl.x_field.mode == CTL_MODE_VALUE) { \ + SET_CID_VALUE(x_cid, x_field, dev->ctl.x_field.value, false); \ + } else if (dev->ctl.x_field.mode == CTL_MODE_DEFAULT) { \ + SET_CID_DEFAULT(x_cid, x_field, false); \ } \ } -# define CONTROL_AUTO_CID(_cid_auto, _cid_manual, _field) { \ - if (dev->ctl._field.mode == CTL_MODE_VALUE) { \ - SET_CID_VALUE(_cid_auto, _field##_auto, 0, true); \ - SET_CID_VALUE(_cid_manual, _field, dev->ctl._field.value, false); \ - } else if (dev->ctl._field.mode == CTL_MODE_AUTO) { \ - SET_CID_VALUE(_cid_auto, _field##_auto, 1, false); \ - } else if (dev->ctl._field.mode == CTL_MODE_DEFAULT) { \ - SET_CID_VALUE(_cid_auto, _field##_auto, 0, true); /* Reset inactive flag */ \ - SET_CID_DEFAULT(_cid_manual, _field, false); \ - SET_CID_DEFAULT(_cid_auto, _field##_auto, false); \ +# define CONTROL_AUTO_CID(x_cid_auto, x_cid_manual, x_field) { \ + if (dev->ctl.x_field.mode == CTL_MODE_VALUE) { \ + SET_CID_VALUE(x_cid_auto, x_field##_auto, 0, true); \ + SET_CID_VALUE(x_cid_manual, x_field, dev->ctl.x_field.value, false); \ + } else if (dev->ctl.x_field.mode == CTL_MODE_AUTO) { \ + SET_CID_VALUE(x_cid_auto, x_field##_auto, 1, false); \ + } else if (dev->ctl.x_field.mode == CTL_MODE_DEFAULT) { \ + SET_CID_VALUE(x_cid_auto, x_field##_auto, 0, true); /* Reset inactive flag */ \ + SET_CID_DEFAULT(x_cid_manual, x_field, false); \ + SET_CID_DEFAULT(x_cid_auto, x_field##_auto, false); \ } \ } @@ -830,16 +830,16 @@ static void _device_apply_controls(device_s *dev) { } static int _device_query_control( - device_s *dev, struct v4l2_queryctrl *query, + us_device_s *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, bool quiet) { // cppcheck-suppress redundantPointerOp - MEMSET_ZERO(*query); + US_MEMSET_ZERO(*query); query->id = cid; - if (D_XIOCTL(VIDIOC_QUERYCTRL, query) < 0 || query->flags & V4L2_CTRL_FLAG_DISABLED) { + if (_D_XIOCTL(VIDIOC_QUERYCTRL, query) < 0 || query->flags & V4L2_CTRL_FLAG_DISABLED) { if (!quiet) { - LOG_ERROR("Changing control %s is unsupported", name); + US_LOG_ERROR("Changing control %s is unsupported", name); } return -1; } @@ -847,12 +847,12 @@ static int _device_query_control( } static void _device_set_control( - device_s *dev, struct v4l2_queryctrl *query, + us_device_s *dev, struct v4l2_queryctrl *query, const char *name, unsigned cid, int value, bool quiet) { if (value < query->minimum || value > query->maximum || value % query->step != 0) { if (!quiet) { - LOG_ERROR("Invalid value %d of control %s: min=%d, max=%d, default=%d, step=%u", + US_LOG_ERROR("Invalid value %d of control %s: min=%d, max=%d, default=%d, step=%u", value, name, query->minimum, query->maximum, query->default_value, query->step); } return; @@ -862,17 +862,17 @@ static void _device_set_control( ctl.id = cid; ctl.value = value; - if (D_XIOCTL(VIDIOC_S_CTRL, &ctl) < 0) { + if (_D_XIOCTL(VIDIOC_S_CTRL, &ctl) < 0) { if (!quiet) { - LOG_PERROR("Can't set control %s", name); + US_LOG_PERROR("Can't set control %s", name); } } else if (!quiet) { - LOG_INFO("Applying control %s: %d", name, ctl.value); + US_LOG_INFO("Applying control %s: %d", name, ctl.value); } } static const char *_format_to_string_nullable(unsigned format) { - for (unsigned index = 0; index < ARRAY_LEN(_FORMATS); ++index) { + for (unsigned index = 0; index < US_ARRAY_LEN(_FORMATS); ++index) { if (format == _FORMATS[index].format) { return _FORMATS[index].name; } @@ -886,7 +886,7 @@ static const char *_format_to_string_supported(unsigned format) { } static const char *_standard_to_string(v4l2_std_id standard) { - for (unsigned index = 0; index < ARRAY_LEN(_STANDARDS); ++index) { + for (unsigned index = 0; index < US_ARRAY_LEN(_STANDARDS); ++index) { if (standard == _STANDARDS[index].standard) { return _STANDARDS[index].name; } @@ -895,13 +895,10 @@ static const char *_standard_to_string(v4l2_std_id standard) { } static const char *_io_method_to_string_supported(enum v4l2_memory io_method) { - for (unsigned index = 0; index < ARRAY_LEN(_IO_METHODS); ++index) { + for (unsigned index = 0; index < US_ARRAY_LEN(_IO_METHODS); ++index) { if (io_method == _IO_METHODS[index].io_method) { return _IO_METHODS[index].name; } } return "unsupported"; } - -#undef D_XIOCTL -#undef RUN diff --git a/src/ustreamer/device.h b/src/ustreamer/device.h index 4c212f8..244bcb5 100644 --- a/src/ustreamer/device.h +++ b/src/ustreamer/device.h @@ -48,73 +48,73 @@ #include "../libs/xioctl.h" -#define VIDEO_MIN_WIDTH ((unsigned)160) -#define VIDEO_MAX_WIDTH ((unsigned)10240) +#define US_VIDEO_MIN_WIDTH ((unsigned)160) +#define US_VIDEO_MAX_WIDTH ((unsigned)10240) -#define VIDEO_MIN_HEIGHT ((unsigned)120) -#define VIDEO_MAX_HEIGHT ((unsigned)4320) +#define US_VIDEO_MIN_HEIGHT ((unsigned)120) +#define US_VIDEO_MAX_HEIGHT ((unsigned)4320) -#define VIDEO_MAX_FPS ((unsigned)120) +#define US_VIDEO_MAX_FPS ((unsigned)120) -#define STANDARD_UNKNOWN V4L2_STD_UNKNOWN -#define STANDARDS_STR "PAL, NTSC, SECAM" +#define US_STANDARD_UNKNOWN V4L2_STD_UNKNOWN +#define US_STANDARDS_STR "PAL, NTSC, SECAM" -#define FORMAT_UNKNOWN -1 -#define FORMATS_STR "YUYV, UYVY, RGB565, RGB24, MJPEG, JPEG" +#define US_FORMAT_UNKNOWN -1 +#define US_FORMATS_STR "YUYV, UYVY, RGB565, RGB24, MJPEG, JPEG" -#define IO_METHOD_UNKNOWN -1 -#define IO_METHODS_STR "MMAP, USERPTR" +#define US_IO_METHOD_UNKNOWN -1 +#define US_IO_METHODS_STR "MMAP, USERPTR" typedef struct { - frame_s raw; + us_frame_s raw; struct v4l2_buffer buf; int dma_fd; bool grabbed; -} hw_buffer_s; +} us_hw_buffer_s; typedef struct { - int fd; - unsigned width; - unsigned height; - unsigned format; - unsigned stride; - unsigned hw_fps; - unsigned jpeg_quality; - size_t raw_size; - unsigned n_bufs; - hw_buffer_s *hw_bufs; - bool capturing; - bool persistent_timeout_reported; -} device_runtime_s; + int fd; + unsigned width; + unsigned height; + unsigned format; + unsigned stride; + unsigned hw_fps; + unsigned jpeg_quality; + size_t raw_size; + unsigned n_bufs; + us_hw_buffer_s *hw_bufs; + bool capturing; + bool persistent_timeout_reported; +} us_device_runtime_s; typedef enum { CTL_MODE_NONE = 0, CTL_MODE_VALUE, CTL_MODE_AUTO, CTL_MODE_DEFAULT, -} control_mode_e; +} us_control_mode_e; typedef struct { - control_mode_e mode; - int value; -} control_s; + us_control_mode_e mode; + int value; +} us_control_s; 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 rotate; - control_s flip_vertical; - control_s flip_horizontal; -} controls_s; + us_control_s brightness; + us_control_s contrast; + us_control_s saturation; + us_control_s hue; + us_control_s gamma; + us_control_s sharpness; + us_control_s backlight_compensation; + us_control_s white_balance; + us_control_s gain; + us_control_s color_effect; + us_control_s rotate; + us_control_s flip_vertical; + us_control_s flip_horizontal; +} us_controls_s; typedef struct { char *path; @@ -132,25 +132,25 @@ typedef struct { bool persistent; unsigned timeout; - controls_s ctl; + us_controls_s ctl; - device_runtime_s *run; -} device_s; + us_device_runtime_s *run; +} us_device_s; -device_s *device_init(void); -void device_destroy(device_s *dev); +us_device_s *us_device_init(void); +void us_device_destroy(us_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 us_device_parse_format(const char *str); +v4l2_std_id us_device_parse_standard(const char *str); +int us_device_parse_io_method(const char *str); -int device_open(device_s *dev); -void device_close(device_s *dev); +int us_device_open(us_device_s *dev); +void us_device_close(us_device_s *dev); -int device_export_to_dma(device_s *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, hw_buffer_s **hw); -int device_release_buffer(device_s *dev, hw_buffer_s *hw); -int device_consume_event(device_s *dev); +int us_device_export_to_dma(us_device_s *dev); +int us_device_switch_capturing(us_device_s *dev, bool enable); +int us_device_select(us_device_s *dev, bool *has_read, bool *has_write, bool *has_error); +int us_device_grab_buffer(us_device_s *dev, us_hw_buffer_s **hw); +int us_device_release_buffer(us_device_s *dev, us_hw_buffer_s *hw); +int us_device_consume_event(us_device_s *dev); diff --git a/src/ustreamer/encoder.c b/src/ustreamer/encoder.c index a865078..29f25c4 100644 --- a/src/ustreamer/encoder.c +++ b/src/ustreamer/encoder.c @@ -25,67 +25,67 @@ static const struct { const char *name; - const encoder_type_e type; + const us_encoder_type_e type; } _ENCODER_TYPES[] = { - {"CPU", ENCODER_TYPE_CPU}, - {"HW", ENCODER_TYPE_HW}, - {"M2M-VIDEO", ENCODER_TYPE_M2M_VIDEO}, - {"M2M-IMAGE", ENCODER_TYPE_M2M_IMAGE}, - {"M2M-MJPEG", ENCODER_TYPE_M2M_VIDEO}, - {"M2M-JPEG", ENCODER_TYPE_M2M_IMAGE}, - {"OMX", ENCODER_TYPE_M2M_IMAGE}, - {"NOOP", ENCODER_TYPE_NOOP}, + {"CPU", US_ENCODER_TYPE_CPU}, + {"HW", US_ENCODER_TYPE_HW}, + {"M2M-VIDEO", US_ENCODER_TYPE_M2M_VIDEO}, + {"M2M-IMAGE", US_ENCODER_TYPE_M2M_IMAGE}, + {"M2M-MJPEG", US_ENCODER_TYPE_M2M_VIDEO}, + {"M2M-JPEG", US_ENCODER_TYPE_M2M_IMAGE}, + {"OMX", US_ENCODER_TYPE_M2M_IMAGE}, + {"NOOP", US_ENCODER_TYPE_NOOP}, }; static void *_worker_job_init(void *v_enc); static void _worker_job_destroy(void *v_job); -static bool _worker_run_job(worker_s *wr); +static bool _worker_run_job(us_worker_s *wr); -#define ER(_next) enc->run->_next +#define _ER(x_next) enc->run->x_next -encoder_s *encoder_init(void) { - encoder_runtime_s *run; - A_CALLOC(run, 1); - run->type = ENCODER_TYPE_CPU; +us_encoder_s *us_encoder_init(void) { + us_encoder_runtime_s *run; + US_CALLOC(run, 1); + run->type = US_ENCODER_TYPE_CPU; run->quality = 80; - A_MUTEX_INIT(&run->mutex); + US_MUTEX_INIT(&run->mutex); - encoder_s *enc; - A_CALLOC(enc, 1); + us_encoder_s *enc; + US_CALLOC(enc, 1); enc->type = run->type; - enc->n_workers = get_cores_available(); + enc->n_workers = us_get_cores_available(); enc->run = run; return enc; } -void encoder_destroy(encoder_s *enc) { - if (ER(m2ms)) { - for (unsigned index = 0; index < ER(n_m2ms); ++index) { - if (ER(m2ms[index])) { - m2m_encoder_destroy(ER(m2ms[index])); +void us_encoder_destroy(us_encoder_s *enc) { + if (_ER(m2ms)) { + for (unsigned index = 0; index < _ER(n_m2ms); ++index) { + if (_ER(m2ms[index])) { + us_m2m_encoder_destroy(_ER(m2ms[index])); } } - free(ER(m2ms)); + free(_ER(m2ms)); } - A_MUTEX_DESTROY(&ER(mutex)); + US_MUTEX_DESTROY(&_ER(mutex)); free(enc->run); free(enc); } -encoder_type_e encoder_parse_type(const char *str) { - for (unsigned index = 0; index < ARRAY_LEN(_ENCODER_TYPES); ++index) { +us_encoder_type_e us_encoder_parse_type(const char *str) { + for (unsigned index = 0; index < US_ARRAY_LEN(_ENCODER_TYPES); ++index) { if (!strcasecmp(str, _ENCODER_TYPES[index].name)) { return _ENCODER_TYPES[index].type; } } - return ENCODER_TYPE_UNKNOWN; + return US_ENCODER_TYPE_UNKNOWN; } -const char *encoder_type_to_string(encoder_type_e type) { - for (unsigned index = 0; index < ARRAY_LEN(_ENCODER_TYPES); ++index) { +const char *us_encoder_type_to_string(us_encoder_type_e type) { + for (unsigned index = 0; index < US_ARRAY_LEN(_ENCODER_TYPES); ++index) { if (_ENCODER_TYPES[index].type == type) { return _ENCODER_TYPES[index].name; } @@ -93,44 +93,44 @@ const char *encoder_type_to_string(encoder_type_e type) { return _ENCODER_TYPES[0].name; } -workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev) { -# define DR(_next) dev->run->_next +us_workers_pool_s *us_encoder_workers_pool_init(us_encoder_s *enc, us_device_s *dev) { +# define DR(x_next) dev->run->x_next - encoder_type_e type = (ER(cpu_forced) ? ENCODER_TYPE_CPU : enc->type); + us_encoder_type_e type = (_ER(cpu_forced) ? US_ENCODER_TYPE_CPU : enc->type); unsigned quality = dev->jpeg_quality; - unsigned n_workers = min_u(enc->n_workers, DR(n_bufs)); + unsigned n_workers = us_min_u(enc->n_workers, DR(n_bufs)); bool cpu_forced = false; - if (is_jpeg(DR(format)) && type != ENCODER_TYPE_HW) { - LOG_INFO("Switching to HW encoder: the input is (M)JPEG ..."); - type = ENCODER_TYPE_HW; + if (us_is_jpeg(DR(format)) && type != US_ENCODER_TYPE_HW) { + US_LOG_INFO("Switching to HW encoder: the input is (M)JPEG ..."); + type = US_ENCODER_TYPE_HW; } - if (type == ENCODER_TYPE_HW) { - if (!is_jpeg(DR(format))) { - LOG_INFO("Switching to CPU encoder: the input format is not (M)JPEG ..."); + if (type == US_ENCODER_TYPE_HW) { + if (!us_is_jpeg(DR(format))) { + US_LOG_INFO("Switching to CPU encoder: the input format is not (M)JPEG ..."); goto use_cpu; } quality = DR(jpeg_quality); n_workers = 1; - } else if (type == ENCODER_TYPE_M2M_VIDEO || type == ENCODER_TYPE_M2M_IMAGE) { - LOG_DEBUG("Preparing M2M-%s encoder ...", (type == ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE")); - if (ER(m2ms) == NULL) { - A_CALLOC(ER(m2ms), n_workers); + } else if (type == US_ENCODER_TYPE_M2M_VIDEO || type == US_ENCODER_TYPE_M2M_IMAGE) { + US_LOG_DEBUG("Preparing M2M-%s encoder ...", (type == US_ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE")); + if (_ER(m2ms) == NULL) { + US_CALLOC(_ER(m2ms), n_workers); } - for (; ER(n_m2ms) < n_workers; ++ER(n_m2ms)) { + for (; _ER(n_m2ms) < n_workers; ++_ER(n_m2ms)) { // Начинаем с нуля и доинициализируем на следующих заходах при необходимости char name[32]; - snprintf(name, 32, "JPEG-%u", ER(n_m2ms)); - if (type == ENCODER_TYPE_M2M_VIDEO) { - ER(m2ms[ER(n_m2ms)]) = m2m_mjpeg_encoder_init(name, enc->m2m_path, quality); + snprintf(name, 32, "JPEG-%u", _ER(n_m2ms)); + if (type == US_ENCODER_TYPE_M2M_VIDEO) { + _ER(m2ms[_ER(n_m2ms)]) = us_m2m_mjpeg_encoder_init(name, enc->m2m_path, quality); } else { - ER(m2ms[ER(n_m2ms)]) = m2m_jpeg_encoder_init(name, enc->m2m_path, quality); + _ER(m2ms[_ER(n_m2ms)]) = us_m2m_jpeg_encoder_init(name, enc->m2m_path, quality); } } - } else if (type == ENCODER_TYPE_NOOP) { + } else if (type == US_ENCODER_TYPE_NOOP) { n_workers = 1; quality = 0; } @@ -138,32 +138,32 @@ workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev) { goto ok; use_cpu: - type = ENCODER_TYPE_CPU; + type = US_ENCODER_TYPE_CPU; quality = dev->jpeg_quality; ok: - if (type == ENCODER_TYPE_NOOP) { - LOG_INFO("Using JPEG NOOP encoder"); + if (type == US_ENCODER_TYPE_NOOP) { + US_LOG_INFO("Using JPEG NOOP encoder"); } else if (quality == 0) { - LOG_INFO("Using JPEG quality: encoder default"); + US_LOG_INFO("Using JPEG quality: encoder default"); } else { - LOG_INFO("Using JPEG quality: %u%%", quality); + US_LOG_INFO("Using JPEG quality: %u%%", quality); } - A_MUTEX_LOCK(&ER(mutex)); - ER(type) = type; - ER(quality) = quality; + US_MUTEX_LOCK(&_ER(mutex)); + _ER(type) = type; + _ER(quality) = quality; if (cpu_forced) { - ER(cpu_forced) = true; + _ER(cpu_forced) = true; } - A_MUTEX_UNLOCK(&ER(mutex)); + 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; } - return workers_pool_init( + return us_workers_pool_init( "JPEG", "jw", n_workers, desired_interval, _worker_job_init, (void *)enc, _worker_job_destroy, @@ -172,64 +172,61 @@ workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev) { # undef DR } -void encoder_get_runtime_params(encoder_s *enc, encoder_type_e *type, unsigned *quality) { - A_MUTEX_LOCK(&ER(mutex)); - *type = ER(type); - *quality = ER(quality); - A_MUTEX_UNLOCK(&ER(mutex)); +void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, unsigned *quality) { + US_MUTEX_LOCK(&_ER(mutex)); + *type = _ER(type); + *quality = _ER(quality); + US_MUTEX_UNLOCK(&_ER(mutex)); } static void *_worker_job_init(void *v_enc) { - encoder_job_s *job; - A_CALLOC(job, 1); - job->enc = (encoder_s *)v_enc; - job->dest = frame_init(); + us_encoder_job_s *job; + US_CALLOC(job, 1); + job->enc = (us_encoder_s *)v_enc; + job->dest = us_frame_init(); return (void *)job; } static void _worker_job_destroy(void *v_job) { - encoder_job_s *job = (encoder_job_s *)v_job; - frame_destroy(job->dest); + us_encoder_job_s *job = (us_encoder_job_s *)v_job; + us_frame_destroy(job->dest); free(job); } -#undef ER +static bool _worker_run_job(us_worker_s *wr) { + us_encoder_job_s *job = (us_encoder_job_s *)wr->job; + us_encoder_s *enc = job->enc; // Just for _ER() + us_frame_s *src = &job->hw->raw; + us_frame_s *dest = job->dest; -static bool _worker_run_job(worker_s *wr) { - encoder_job_s *job = (encoder_job_s *)wr->job; - frame_s *src = &job->hw->raw; - frame_s *dest = job->dest; + assert(_ER(type) != US_ENCODER_TYPE_UNKNOWN); -# define ER(_next) job->enc->run->_next - - assert(ER(type) != ENCODER_TYPE_UNKNOWN); - - if (ER(type) == ENCODER_TYPE_CPU) { - LOG_VERBOSE("Compressing JPEG using CPU: worker=%s, buffer=%u", + if (_ER(type) == US_ENCODER_TYPE_CPU) { + US_LOG_VERBOSE("Compressing JPEG using CPU: worker=%s, buffer=%u", wr->name, job->hw->buf.index); - cpu_encoder_compress(src, dest, ER(quality)); + us_cpu_encoder_compress(src, dest, _ER(quality)); - } else if (ER(type) == ENCODER_TYPE_HW) { - LOG_VERBOSE("Compressing JPEG using HW (just copying): worker=%s, buffer=%u", + } else if (_ER(type) == US_ENCODER_TYPE_HW) { + US_LOG_VERBOSE("Compressing JPEG using HW (just copying): worker=%s, buffer=%u", wr->name, job->hw->buf.index); - hw_encoder_compress(src, dest); + us_hw_encoder_compress(src, dest); - } else if (ER(type) == ENCODER_TYPE_M2M_VIDEO || ER(type) == ENCODER_TYPE_M2M_IMAGE) { - LOG_VERBOSE("Compressing JPEG using M2M-%s: worker=%s, buffer=%u", - (ER(type) == ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE"), wr->name, job->hw->buf.index); - if (m2m_encoder_compress(ER(m2ms[wr->number]), src, dest, false) < 0) { + } else if (_ER(type) == US_ENCODER_TYPE_M2M_VIDEO || _ER(type) == US_ENCODER_TYPE_M2M_IMAGE) { + US_LOG_VERBOSE("Compressing JPEG using M2M-%s: worker=%s, buffer=%u", + (_ER(type) == US_ENCODER_TYPE_M2M_VIDEO ? "VIDEO" : "IMAGE"), wr->name, job->hw->buf.index); + if (us_m2m_encoder_compress(_ER(m2ms[wr->number]), src, dest, false) < 0) { goto error; } - } else if (ER(type) == ENCODER_TYPE_NOOP) { - LOG_VERBOSE("Compressing JPEG using NOOP (do nothing): worker=%s, buffer=%u", + } else if (_ER(type) == US_ENCODER_TYPE_NOOP) { + US_LOG_VERBOSE("Compressing JPEG using NOOP (do nothing): worker=%s, buffer=%u", wr->name, job->hw->buf.index); - frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); + us_frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); usleep(5000); // Просто чтобы работала логика desired_fps - dest->encode_end_ts = get_now_monotonic(); // frame_encoding_end() + dest->encode_end_ts = us_get_now_monotonic(); // us_frame_encoding_end() } - LOG_VERBOSE("Compressed new JPEG: size=%zu, time=%0.3Lf, worker=%s, buffer=%u", + US_LOG_VERBOSE("Compressed new JPEG: size=%zu, time=%0.3Lf, worker=%s, buffer=%u", job->dest->used, job->dest->encode_end_ts - job->dest->encode_begin_ts, wr->name, @@ -238,12 +235,10 @@ static bool _worker_run_job(worker_s *wr) { return true; error: - LOG_ERROR("Compression failed: worker=%s, buffer=%u", wr->name, job->hw->buf.index); - LOG_ERROR("Error while compressing buffer, falling back to CPU"); - A_MUTEX_LOCK(&ER(mutex)); - ER(cpu_forced) = true; - A_MUTEX_UNLOCK(&ER(mutex)); + US_LOG_ERROR("Compression failed: worker=%s, buffer=%u", wr->name, job->hw->buf.index); + US_LOG_ERROR("Error while compressing buffer, falling back to CPU"); + US_MUTEX_LOCK(&_ER(mutex)); + _ER(cpu_forced) = true; + US_MUTEX_UNLOCK(&_ER(mutex)); return false; - -# undef ER } diff --git a/src/ustreamer/encoder.h b/src/ustreamer/encoder.h index 934e4fe..c5ca781 100644 --- a/src/ustreamer/encoder.h +++ b/src/ustreamer/encoder.h @@ -46,46 +46,46 @@ #define ENCODER_TYPES_STR "CPU, HW, M2M-VIDEO, M2M-IMAGE, NOOP" typedef enum { - ENCODER_TYPE_UNKNOWN, // Only for encoder_parse_type() and main() - ENCODER_TYPE_CPU, - ENCODER_TYPE_HW, - ENCODER_TYPE_M2M_VIDEO, - ENCODER_TYPE_M2M_IMAGE, - ENCODER_TYPE_NOOP, -} encoder_type_e; + US_ENCODER_TYPE_UNKNOWN, // Only for us_encoder_parse_type() and main() + US_ENCODER_TYPE_CPU, + US_ENCODER_TYPE_HW, + US_ENCODER_TYPE_M2M_VIDEO, + US_ENCODER_TYPE_M2M_IMAGE, + US_ENCODER_TYPE_NOOP, +} us_encoder_type_e; typedef struct { - encoder_type_e type; - unsigned quality; - bool cpu_forced; - pthread_mutex_t mutex; + us_encoder_type_e type; + unsigned quality; + bool cpu_forced; + pthread_mutex_t mutex; - unsigned n_m2ms; - m2m_encoder_s **m2ms; -} encoder_runtime_s; + unsigned n_m2ms; + us_m2m_encoder_s **m2ms; +} us_encoder_runtime_s; typedef struct { - encoder_type_e type; - unsigned n_workers; - char *m2m_path; + us_encoder_type_e type; + unsigned n_workers; + char *m2m_path; - encoder_runtime_s *run; -} encoder_s; + us_encoder_runtime_s *run; +} us_encoder_s; typedef struct { - encoder_s *enc; - hw_buffer_s *hw; - frame_s *dest; -} encoder_job_s; + us_encoder_s *enc; + us_hw_buffer_s *hw; + us_frame_s *dest; +} us_encoder_job_s; -encoder_s *encoder_init(void); -void encoder_destroy(encoder_s *enc); +us_encoder_s *us_encoder_init(void); +void us_encoder_destroy(us_encoder_s *enc); -encoder_type_e encoder_parse_type(const char *str); -const char *encoder_type_to_string(encoder_type_e type); +us_encoder_type_e us_encoder_parse_type(const char *str); +const char *us_encoder_type_to_string(us_encoder_type_e type); -workers_pool_s *encoder_workers_pool_init(encoder_s *enc, device_s *dev); -void encoder_get_runtime_params(encoder_s *enc, encoder_type_e *type, unsigned *quality); +us_workers_pool_s *us_encoder_workers_pool_init(us_encoder_s *enc, us_device_s *dev); +void us_encoder_get_runtime_params(us_encoder_s *enc, us_encoder_type_e *type, unsigned *quality); -int encoder_compress(encoder_s *enc, unsigned worker_number, frame_s *src, frame_s *dest); +int us_encoder_compress(us_encoder_s *enc, unsigned worker_number, us_frame_s *src, us_frame_s *dest); diff --git a/src/ustreamer/encoders/cpu/encoder.c b/src/ustreamer/encoders/cpu/encoder.c index 9aeedd8..780b79e 100644 --- a/src/ustreamer/encoders/cpu/encoder.c +++ b/src/ustreamer/encoders/cpu/encoder.c @@ -31,26 +31,26 @@ typedef struct { struct jpeg_destination_mgr mgr; // Default manager JOCTET *buf; // Start of buffer - frame_s *frame; + us_frame_s *frame; } _jpeg_dest_manager_s; -static void _jpeg_set_dest_frame(j_compress_ptr jpeg, frame_s *frame); +static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame); -static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const frame_s *frame); -static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const frame_s *frame); -static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const frame_s *frame); -static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const frame_s *frame); +static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); +static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); +static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); +static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame); static void _jpeg_init_destination(j_compress_ptr jpeg); static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg); static void _jpeg_term_destination(j_compress_ptr jpeg); -void cpu_encoder_compress(const frame_s *src, frame_s *dest, unsigned quality) { +void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned quality) { // This function based on compress_image_to_jpeg() from mjpg-streamer - frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); + us_frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); struct jpeg_compress_struct jpeg; struct jpeg_error_mgr jpeg_error; @@ -70,8 +70,8 @@ void cpu_encoder_compress(const frame_s *src, frame_s *dest, unsigned quality) { jpeg_start_compress(&jpeg, TRUE); -# define WRITE_SCANLINES(_format, _func) \ - case _format: { _func(&jpeg, src); break; } +# define WRITE_SCANLINES(x_format, x_func) \ + case x_format: { x_func(&jpeg, src); break; } switch (src->format) { // https://www.fourcc.org/yuv.php @@ -87,10 +87,10 @@ void cpu_encoder_compress(const frame_s *src, frame_s *dest, unsigned quality) { jpeg_finish_compress(&jpeg); jpeg_destroy_compress(&jpeg); - frame_encoding_end(dest); + us_frame_encoding_end(dest); } -static void _jpeg_set_dest_frame(j_compress_ptr jpeg, frame_s *frame) { +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) @@ -111,11 +111,11 @@ static void _jpeg_set_dest_frame(j_compress_ptr jpeg, frame_s *frame) { #define YUV_B(_y, _u, _) (((_y) + (454 * (_u))) >> 8) #define NORM_COMPONENT(_x) (((_x) > 255) ? 255 : (((_x) < 0) ? 0 : (_x))) -static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const frame_s *frame) { +static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { uint8_t *line_buf; - A_CALLOC(line_buf, frame->width * 3); + US_CALLOC(line_buf, frame->width * 3); - const unsigned padding = frame_get_padding(frame); + const unsigned padding = us_frame_get_padding(frame); const uint8_t *data = frame->data; unsigned z = 0; @@ -149,11 +149,11 @@ static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const free(line_buf); } -static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const frame_s *frame) { +static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { uint8_t *line_buf; - A_CALLOC(line_buf, frame->width * 3); + US_CALLOC(line_buf, frame->width * 3); - const unsigned padding = frame_get_padding(frame); + const unsigned padding = us_frame_get_padding(frame); const uint8_t *data = frame->data; unsigned z = 0; @@ -192,11 +192,11 @@ static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const #undef YUV_G #undef YUV_R -static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const frame_s *frame) { +static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { uint8_t *line_buf; - A_CALLOC(line_buf, frame->width * 3); + US_CALLOC(line_buf, frame->width * 3); - const unsigned padding = frame_get_padding(frame); + const unsigned padding = us_frame_get_padding(frame); const uint8_t *data = frame->data; while (jpeg->next_scanline < frame->height) { @@ -220,8 +220,8 @@ static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, cons free(line_buf); } -static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const frame_s *frame) { - const unsigned padding = frame_get_padding(frame); +static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) { + const unsigned padding = us_frame_get_padding(frame); uint8_t *data = frame->data; while (jpeg->next_scanline < frame->height) { @@ -251,7 +251,7 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg) { _jpeg_dest_manager_s *dest = (_jpeg_dest_manager_s *)jpeg->dest; - frame_append_data(dest->frame, dest->buf, JPEG_OUTPUT_BUFFER_SIZE); + us_frame_append_data(dest->frame, dest->buf, JPEG_OUTPUT_BUFFER_SIZE); dest->mgr.next_output_byte = dest->buf; dest->mgr.free_in_buffer = JPEG_OUTPUT_BUFFER_SIZE; @@ -267,7 +267,7 @@ static void _jpeg_term_destination(j_compress_ptr jpeg) { size_t final = JPEG_OUTPUT_BUFFER_SIZE - dest->mgr.free_in_buffer; // Write any data remaining in the buffer. - frame_append_data(dest->frame, dest->buf, final); + us_frame_append_data(dest->frame, dest->buf, final); } #undef JPEG_OUTPUT_BUFFER_SIZE diff --git a/src/ustreamer/encoders/cpu/encoder.h b/src/ustreamer/encoders/cpu/encoder.h index 7aaf1b1..ab30f2c 100644 --- a/src/ustreamer/encoders/cpu/encoder.h +++ b/src/ustreamer/encoders/cpu/encoder.h @@ -35,4 +35,4 @@ #include "../../../libs/frame.h" -void cpu_encoder_compress(const frame_s *src, frame_s *dest, unsigned quality); +void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned quality); diff --git a/src/ustreamer/encoders/hw/encoder.c b/src/ustreamer/encoders/hw/encoder.c index 901e32a..3e646d7 100644 --- a/src/ustreamer/encoders/hw/encoder.c +++ b/src/ustreamer/encoders/hw/encoder.c @@ -28,17 +28,17 @@ #include "encoder.h" -void _copy_plus_huffman(const frame_s *src, frame_s *dest); +void _copy_plus_huffman(const us_frame_s *src, us_frame_s *dest); static bool _is_huffman(const uint8_t *data); -void hw_encoder_compress(const frame_s *src, frame_s *dest) { - assert(is_jpeg(src->format)); +void us_hw_encoder_compress(const us_frame_s *src, us_frame_s *dest) { + assert(us_is_jpeg(src->format)); _copy_plus_huffman(src, dest); } -void _copy_plus_huffman(const frame_s *src, frame_s *dest) { - frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); +void _copy_plus_huffman(const us_frame_s *src, us_frame_s *dest) { + us_frame_encoding_begin(src, dest, V4L2_PIX_FMT_JPEG); if (!_is_huffman(src->data)) { const uint8_t *src_ptr = src->data; @@ -54,15 +54,15 @@ void _copy_plus_huffman(const frame_s *src, frame_s *dest) { const size_t paste = src_ptr - src->data; - frame_set_data(dest, src->data, paste); - frame_append_data(dest, HUFFMAN_TABLE, sizeof(HUFFMAN_TABLE)); - frame_append_data(dest, src_ptr, src->used - paste); + us_frame_set_data(dest, src->data, paste); + us_frame_append_data(dest, US_HUFFMAN_TABLE, sizeof(US_HUFFMAN_TABLE)); + us_frame_append_data(dest, src_ptr, src->used - paste); } else { - frame_set_data(dest, src->data, src->used); + us_frame_set_data(dest, src->data, src->used); } - frame_encoding_end(dest); + us_frame_encoding_end(dest); } static bool _is_huffman(const uint8_t *data) { diff --git a/src/ustreamer/encoders/hw/encoder.h b/src/ustreamer/encoders/hw/encoder.h index c81af6c..c9c8bd3 100644 --- a/src/ustreamer/encoders/hw/encoder.h +++ b/src/ustreamer/encoders/hw/encoder.h @@ -34,4 +34,4 @@ #include "huffman.h" -void hw_encoder_compress(const frame_s *src, frame_s *dest); +void us_hw_encoder_compress(const us_frame_s *src, us_frame_s *dest); diff --git a/src/ustreamer/encoders/hw/huffman.h b/src/ustreamer/encoders/hw/huffman.h index 2de8d34..c2ab132 100644 --- a/src/ustreamer/encoders/hw/huffman.h +++ b/src/ustreamer/encoders/hw/huffman.h @@ -30,7 +30,7 @@ #include -static const uint8_t HUFFMAN_TABLE[] = { +static const uint8_t US_HUFFMAN_TABLE[] = { 0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, 0x03, diff --git a/src/ustreamer/gpio/gpio.c b/src/ustreamer/gpio/gpio.c index 54e41ed..990be5e 100644 --- a/src/ustreamer/gpio/gpio.c +++ b/src/ustreamer/gpio/gpio.c @@ -23,13 +23,13 @@ #include "gpio.h" -gpio_s us_gpio = { +us_gpio_s us_gpio = { .path = "/dev/gpiochip0", .consumer_prefix = "ustreamer", -# define MAKE_OUTPUT(_role) { \ +# define MAKE_OUTPUT(x_role) { \ .pin = -1, \ - .role = _role, \ + .role = x_role, \ .consumer = NULL, \ .line = NULL, \ .state = false \ @@ -46,77 +46,77 @@ gpio_s us_gpio = { }; -static void _gpio_output_init(gpio_output_s *output); -static void _gpio_output_destroy(gpio_output_s *output); +static void _gpio_output_init(us_gpio_output_s *output); +static void _gpio_output_destroy(us_gpio_output_s *output); -void gpio_init(void) { +void us_gpio_init(void) { assert(us_gpio.chip == NULL); if ( us_gpio.prog_running.pin >= 0 || us_gpio.stream_online.pin >= 0 || us_gpio.has_http_clients.pin >= 0 ) { - A_MUTEX_INIT(&us_gpio.mutex); - LOG_INFO("GPIO: Using chip device: %s", us_gpio.path); + US_MUTEX_INIT(&us_gpio.mutex); + US_LOG_INFO("GPIO: Using chip device: %s", us_gpio.path); if ((us_gpio.chip = gpiod_chip_open(us_gpio.path)) != NULL) { _gpio_output_init(&us_gpio.prog_running); _gpio_output_init(&us_gpio.stream_online); _gpio_output_init(&us_gpio.has_http_clients); } else { - LOG_PERROR("GPIO: Can't initialize chip device %s", us_gpio.path); + US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_gpio.path); } } } -void gpio_destroy(void) { +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) { gpiod_chip_close(us_gpio.chip); us_gpio.chip = NULL; - A_MUTEX_DESTROY(&us_gpio.mutex); + US_MUTEX_DESTROY(&us_gpio.mutex); } } -int gpio_inner_set(gpio_output_s *output, bool state) { +int us_gpio_inner_set(us_gpio_output_s *output, bool state) { int retval = 0; assert(us_gpio.chip); assert(output->line); assert(output->state != state); // Must be checked in macro for the performance - A_MUTEX_LOCK(&us_gpio.mutex); + US_MUTEX_LOCK(&us_gpio.mutex); if (gpiod_line_set_value(output->line, (int)state) < 0) { \ - LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \ + US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \ _gpio_output_destroy(output); retval = -1; } - A_MUTEX_UNLOCK(&us_gpio.mutex); + US_MUTEX_UNLOCK(&us_gpio.mutex); return retval; } -static void _gpio_output_init(gpio_output_s *output) { +static void _gpio_output_init(us_gpio_output_s *output) { assert(us_gpio.chip); assert(output->line == NULL); - A_ASPRINTF(output->consumer, "%s::%s", us_gpio.consumer_prefix, output->role); + US_ASPRINTF(output->consumer, "%s::%s", us_gpio.consumer_prefix, output->role); if (output->pin >= 0) { if ((output->line = gpiod_chip_get_line(us_gpio.chip, output->pin)) != NULL) { if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) { - LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer); + US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer); _gpio_output_destroy(output); } } else { - LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer); + US_LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer); } } } -static void _gpio_output_destroy(gpio_output_s *output) { +static void _gpio_output_destroy(us_gpio_output_s *output) { if (output->line) { gpiod_line_release(output->line); output->line = NULL; diff --git a/src/ustreamer/gpio/gpio.h b/src/ustreamer/gpio/gpio.h index 523bec2..b5c87f7 100644 --- a/src/ustreamer/gpio/gpio.h +++ b/src/ustreamer/gpio/gpio.h @@ -41,46 +41,46 @@ typedef struct { char *consumer; struct gpiod_line *line; bool state; -} gpio_output_s; +} us_gpio_output_s; typedef struct { - char *path; - char *consumer_prefix; + char *path; + char *consumer_prefix; - gpio_output_s prog_running; - gpio_output_s stream_online; - gpio_output_s has_http_clients; + us_gpio_output_s prog_running; + us_gpio_output_s stream_online; + us_gpio_output_s has_http_clients; pthread_mutex_t mutex; struct gpiod_chip *chip; -} gpio_s; +} us_gpio_s; -extern gpio_s us_gpio; +extern us_gpio_s us_gpio; -void gpio_init(void); -void gpio_destroy(void); -int gpio_inner_set(gpio_output_s *output, bool state); +void us_gpio_init(void); +void us_gpio_destroy(void); +int us_gpio_inner_set(us_gpio_output_s *output, bool state); -#define SET_STATE(_output, _state) { \ - if (_output.line && _output.state != _state) { \ - if (!gpio_inner_set(&_output, _state)) { \ - _output.state = _state; \ +#define SET_STATE(x_output, x_state) { \ + if (x_output.line && x_output.state != x_state) { \ + if (!us_gpio_inner_set(&x_output, x_state)) { \ + x_output.state = x_state; \ } \ } \ } -INLINE void gpio_set_prog_running(bool state) { +INLINE void us_gpio_set_prog_running(bool state) { SET_STATE(us_gpio.prog_running, state); } -INLINE void gpio_set_stream_online(bool state) { +INLINE void us_gpio_set_stream_online(bool state) { SET_STATE(us_gpio.stream_online, state); } -INLINE void gpio_set_has_http_clients(bool state) { +INLINE void us_gpio_set_has_http_clients(bool state) { SET_STATE(us_gpio.has_http_clients, state); } diff --git a/src/ustreamer/h264/stream.c b/src/ustreamer/h264/stream.c index 2444595..6964f5d 100644 --- a/src/ustreamer/h264/stream.c +++ b/src/ustreamer/h264/stream.c @@ -23,42 +23,42 @@ #include "stream.h" -h264_stream_s *h264_stream_init(memsink_s *sink, const char *path, unsigned bitrate, unsigned gop) { - h264_stream_s *h264; - A_CALLOC(h264, 1); +us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, unsigned bitrate, unsigned gop) { + us_h264_stream_s *h264; + US_CALLOC(h264, 1); h264->sink = sink; - h264->tmp_src = frame_init(); - h264->dest = frame_init(); + h264->tmp_src = us_frame_init(); + h264->dest = us_frame_init(); atomic_init(&h264->online, false); - h264->enc = m2m_h264_encoder_init("H264", path, bitrate, gop); + h264->enc = us_m2m_h264_encoder_init("H264", path, bitrate, gop); return h264; } -void h264_stream_destroy(h264_stream_s *h264) { - m2m_encoder_destroy(h264->enc); - frame_destroy(h264->dest); - frame_destroy(h264->tmp_src); +void us_h264_stream_destroy(us_h264_stream_s *h264) { + us_m2m_encoder_destroy(h264->enc); + us_frame_destroy(h264->dest); + us_frame_destroy(h264->tmp_src); free(h264); } -void h264_stream_process(h264_stream_s *h264, const frame_s *frame, bool force_key) { - if (!memsink_server_check(h264->sink, frame)) { +void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, bool force_key) { + if (!us_memsink_server_check(h264->sink, frame)) { return; } - if (is_jpeg(frame->format)) { - long double now = get_now_monotonic(); - LOG_DEBUG("H264: Input frame is JPEG; decoding ..."); - if (unjpeg(frame, h264->tmp_src, true) < 0) { + if (us_is_jpeg(frame->format)) { + 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; } frame = h264->tmp_src; - LOG_VERBOSE("H264: JPEG decoded; time=%.3Lf", get_now_monotonic() - now); + US_LOG_VERBOSE("H264: JPEG decoded; time=%.3Lf", us_get_now_monotonic() - now); } bool online = false; - if (!m2m_encoder_compress(h264->enc, frame, h264->dest, force_key)) { - online = !memsink_server_put(h264->sink, h264->dest); + if (!us_m2m_encoder_compress(h264->enc, frame, h264->dest, force_key)) { + online = !us_memsink_server_put(h264->sink, h264->dest); } atomic_store(&h264->online, online); } diff --git a/src/ustreamer/h264/stream.h b/src/ustreamer/h264/stream.h index fb4dab5..416b740 100644 --- a/src/ustreamer/h264/stream.h +++ b/src/ustreamer/h264/stream.h @@ -35,14 +35,14 @@ typedef struct { - memsink_s *sink; - frame_s *tmp_src; - frame_s *dest; - m2m_encoder_s *enc; - atomic_bool online; -} h264_stream_s; + us_memsink_s *sink; + us_frame_s *tmp_src; + us_frame_s *dest; + us_m2m_encoder_s *enc; + atomic_bool online; +} us_h264_stream_s; -h264_stream_s *h264_stream_init(memsink_s *sink, const char *path, unsigned bitrate, unsigned gop); -void h264_stream_destroy(h264_stream_s *h264); -void h264_stream_process(h264_stream_s *h264, const frame_s *frame, bool force_key); +us_h264_stream_s *us_h264_stream_init(us_memsink_s *sink, const char *path, unsigned bitrate, unsigned gop); +void us_h264_stream_destroy(us_h264_stream_s *h264); +void us_h264_stream_process(us_h264_stream_s *h264, const us_frame_s *frame, bool force_key); diff --git a/src/ustreamer/http/bev.c b/src/ustreamer/http/bev.c index 9ca9a10..96271aa 100644 --- a/src/ustreamer/http/bev.c +++ b/src/ustreamer/http/bev.c @@ -23,25 +23,25 @@ #include "bev.h" -char *bufferevent_my_format_reason(short what) { +char *us_bufferevent_format_reason(short what) { char *reason; - A_CALLOC(reason, 2048); + US_CALLOC(reason, 2048); char perror_buf[1024] = {0}; - char *perror_ptr = errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024); // evutil_socket_error_to_string() is not thread-safe + char *perror_ptr = us_errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024); // evutil_socket_error_to_string() is not thread-safe bool first = true; strcat(reason, perror_ptr); strcat(reason, " ("); -# define FILL_REASON(_bev, _name) { \ - if (what & _bev) { \ +# define FILL_REASON(x_bev, x_name) { \ + if (what & x_bev) { \ if (first) { \ first = false; \ } else { \ strcat(reason, ","); \ } \ - strcat(reason, _name); \ + strcat(reason, x_name); \ } \ } diff --git a/src/ustreamer/http/bev.h b/src/ustreamer/http/bev.h index 4ccdd35..e74bc2d 100644 --- a/src/ustreamer/http/bev.h +++ b/src/ustreamer/http/bev.h @@ -32,4 +32,4 @@ #include "../../libs/logging.h" -char *bufferevent_my_format_reason(short what); +char *us_bufferevent_format_reason(short what); diff --git a/src/ustreamer/http/mime.c b/src/ustreamer/http/mime.c index e1909ba..5551639 100644 --- a/src/ustreamer/http/mime.c +++ b/src/ustreamer/http/mime.c @@ -46,7 +46,7 @@ static const struct { }; -const char *guess_mime_type(const char *path) { +const char *us_guess_mime_type(const char *path) { // FIXME: false-positive cppcheck char *dot = strrchr(path, '.'); // cppcheck-suppress ctunullpointer if (dot == NULL || strchr(dot, '/') != NULL) { @@ -54,7 +54,7 @@ const char *guess_mime_type(const char *path) { } char *ext = dot + 1; - for (unsigned index = 0; index < ARRAY_LEN(_MIME_TYPES); ++index) { + 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; } diff --git a/src/ustreamer/http/mime.h b/src/ustreamer/http/mime.h index ed6e17f..60cf61e 100644 --- a/src/ustreamer/http/mime.h +++ b/src/ustreamer/http/mime.h @@ -29,4 +29,4 @@ #include "../../libs/tools.h" -const char *guess_mime_type(const char *str); +const char *us_guess_mime_type(const char *str); diff --git a/src/ustreamer/http/path.c b/src/ustreamer/http/path.c index a590cfe..0b047c4 100644 --- a/src/ustreamer/http/path.c +++ b/src/ustreamer/http/path.c @@ -23,7 +23,7 @@ #include "path.h" -char *simplify_request_path(const char *str) { +char *us_simplify_request_path(const char *str) { // Based on Lighttpd sources: // - https://github.com/lighttpd/lighttpd1.4/blob/b31e7840d5403bc640579135b7004793b9ccd6c0/src/buffer.c#L840 // - https://github.com/lighttpd/lighttpd1.4/blob/77c01f981725512653c01cde5ca74c11633dfec4/src/t/test_buffer.c @@ -36,7 +36,7 @@ char *simplify_request_path(const char *str) { char *out; char *slash; - A_CALLOC(simplified, strlen(str) + 1); + US_CALLOC(simplified, strlen(str) + 1); if (str[0] == '\0') { simplified[0] = '\0'; @@ -112,7 +112,7 @@ char *simplify_request_path(const char *str) { #ifdef TEST_HTTP_PATH int test_simplify_request_path(const char *sample, const char *expected) { - char *result = simplify_request_path(sample); + char *result = us_simplify_request_path(sample); int retval = -!!strcmp(result, expected); printf("Testing '%s' -> '%s' ... ", sample, expected); diff --git a/src/ustreamer/http/path.h b/src/ustreamer/http/path.h index 394ddfd..1ee1dcd 100644 --- a/src/ustreamer/http/path.h +++ b/src/ustreamer/http/path.h @@ -31,4 +31,4 @@ #include "../../libs/tools.h" -char *simplify_request_path(const char *str); +char *us_simplify_request_path(const char *str); diff --git a/src/ustreamer/http/server.c b/src/ustreamer/http/server.c index db8f499..56b607c 100644 --- a/src/ustreamer/http/server.c +++ b/src/ustreamer/http/server.c @@ -23,7 +23,7 @@ #include "server.h" -static int _http_preprocess_request(struct evhttp_request *request, server_s *server); +static int _http_preprocess_request(struct evhttp_request *request, us_server_s *server); static int _http_check_run_compat_action(struct evhttp_request *request, void *v_server); @@ -38,31 +38,32 @@ static void _http_callback_stream_error(struct bufferevent *buf_event, short wha static void _http_request_watcher(int fd, short event, void *v_server); static void _http_refresher(int fd, short event, void *v_server); -static void _http_queue_send_stream(server_s *server, bool stream_updated, bool frame_updated); +static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bool frame_updated); -static bool _expose_new_frame(server_s *server); +static bool _expose_new_frame(us_server_s *server); +static const char *_http_get_header(struct evhttp_request *request, const char *key); static char *_http_get_client_hostport(struct evhttp_request *request); -#define RUN(_next) server->run->_next -#define STREAM(_next) RUN(stream->_next) -#define VID(_next) STREAM(run->video->_next) -#define EX(_next) RUN(exposed->_next) +#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 _EX(x_next) _RUN(exposed->x_next) -server_s *server_init(stream_s *stream) { - exposed_s *exposed; - A_CALLOC(exposed, 1); - exposed->frame = frame_init(); +us_server_s *us_server_init(us_stream_s *stream) { + us_exposed_s *exposed; + US_CALLOC(exposed, 1); + exposed->frame = us_frame_init(); - server_runtime_s *run; - A_CALLOC(run, 1); + us_server_runtime_s *run; + US_CALLOC(run, 1); run->stream = stream; run->exposed = exposed; - server_s *server; - A_CALLOC(server, 1); + us_server_s *server; + US_CALLOC(server, 1); server->host = "127.0.0.1"; server->port = 8080; server->unix_path = ""; @@ -80,150 +81,146 @@ server_s *server_init(stream_s *stream) { return server; } -void server_destroy(server_s *server) { - if (RUN(refresher)) { - event_del(RUN(refresher)); - event_free(RUN(refresher)); +void us_server_destroy(us_server_s *server) { + if (_RUN(refresher)) { + event_del(_RUN(refresher)); + event_free(_RUN(refresher)); } - if (RUN(request_watcher)) { - event_del(RUN(request_watcher)); - event_free(RUN(request_watcher)); + if (_RUN(request_watcher)) { + event_del(_RUN(request_watcher)); + event_free(_RUN(request_watcher)); } - evhttp_free(RUN(http)); - if (RUN(ext_fd)) { - close(RUN(ext_fd)); + evhttp_free(_RUN(http)); + if (_RUN(ext_fd)) { + close(_RUN(ext_fd)); } - event_base_free(RUN(base)); + event_base_free(_RUN(base)); # if LIBEVENT_VERSION_NUMBER >= 0x02010100 libevent_global_shutdown(); # endif - LIST_ITERATE(RUN(stream_clients), client, { + US_LIST_ITERATE(_RUN(stream_clients), client, { free(client->key); free(client->hostport); free(client); }); - if (RUN(auth_token)) { - free(RUN(auth_token)); + if (_RUN(auth_token)) { + free(_RUN(auth_token)); } - frame_destroy(EX(frame)); - free(RUN(exposed)); + us_frame_destroy(_EX(frame)); + free(_RUN(exposed)); free(server->run); free(server); } -int server_listen(server_s *server) { +int us_server_listen(us_server_s *server) { { if (server->static_path[0] != '\0') { - LOG_INFO("Enabling HTTP file server: %s", server->static_path); - evhttp_set_gencb(RUN(http), _http_callback_static, (void *)server); + US_LOG_INFO("Enabling HTTP file server: %s", server->static_path); + evhttp_set_gencb(_RUN(http), _http_callback_static, (void *)server); } else { - assert(!evhttp_set_cb(RUN(http), "/", _http_callback_root, (void *)server)); + assert(!evhttp_set_cb(_RUN(http), "/", _http_callback_root, (void *)server)); } - assert(!evhttp_set_cb(RUN(http), "/state", _http_callback_state, (void *)server)); - assert(!evhttp_set_cb(RUN(http), "/snapshot", _http_callback_snapshot, (void *)server)); - assert(!evhttp_set_cb(RUN(http), "/stream", _http_callback_stream, (void *)server)); + assert(!evhttp_set_cb(_RUN(http), "/state", _http_callback_state, (void *)server)); + assert(!evhttp_set_cb(_RUN(http), "/snapshot", _http_callback_snapshot, (void *)server)); + assert(!evhttp_set_cb(_RUN(http), "/stream", _http_callback_stream, (void *)server)); } - frame_copy(STREAM(blank), EX(frame)); - EX(notify_last_width) = EX(frame->width); - EX(notify_last_height) = EX(frame->height); + us_frame_copy(_STREAM(blank), _EX(frame)); + _EX(notify_last_width) = _EX(frame->width); + _EX(notify_last_height) = _EX(frame->height); if (server->exit_on_no_clients > 0) { - RUN(last_request_ts) = get_now_monotonic(); + _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(!event_add(RUN(request_watcher), &interval)); + assert((_RUN(request_watcher) = event_new(_RUN(base), -1, EV_PERSIST, _http_request_watcher, server))); + assert(!event_add(_RUN(request_watcher), &interval)); } { struct timeval interval = {0}; - if (STREAM(dev->desired_fps) > 0) { - interval.tv_usec = 1000000 / (STREAM(dev->desired_fps) * 2); + if (_STREAM(dev->desired_fps) > 0) { + interval.tv_usec = 1000000 / (_STREAM(dev->desired_fps) * 2); } else { interval.tv_usec = 16000; // ~60fps } - assert((RUN(refresher) = event_new(RUN(base), -1, EV_PERSIST, _http_refresher, server))); - assert(!event_add(RUN(refresher), &interval)); + assert((_RUN(refresher) = event_new(_RUN(base), -1, EV_PERSIST, _http_refresher, server))); + assert(!event_add(_RUN(refresher), &interval)); } - evhttp_set_timeout(RUN(http), server->timeout); + evhttp_set_timeout(_RUN(http), server->timeout); if (server->user[0] != '\0') { char *encoded_token = NULL; char *raw_token; - A_ASPRINTF(raw_token, "%s:%s", server->user, server->passwd); - base64_encode((uint8_t *)raw_token, strlen(raw_token), &encoded_token, NULL); + US_ASPRINTF(raw_token, "%s:%s", server->user, server->passwd); + us_base64_encode((uint8_t *)raw_token, strlen(raw_token), &encoded_token, NULL); free(raw_token); - A_ASPRINTF(RUN(auth_token), "Basic %s", encoded_token); + US_ASPRINTF(_RUN(auth_token), "Basic %s", encoded_token); free(encoded_token); - LOG_INFO("Using HTTP basic auth"); + US_LOG_INFO("Using HTTP basic auth"); } if (server->unix_path[0] != '\0') { - LOG_DEBUG("Binding HTTP to UNIX socket '%s' ...", server->unix_path); - if ((RUN(ext_fd) = evhttp_my_bind_unix( - RUN(http), + US_LOG_DEBUG("Binding HTTP to UNIX socket '%s' ...", server->unix_path); + if ((_RUN(ext_fd) = us_evhttp_bind_unix( + _RUN(http), server->unix_path, server->unix_rm, server->unix_mode)) < 0 ) { return -1; } - LOG_INFO("Listening HTTP on UNIX socket '%s'", server->unix_path); + US_LOG_INFO("Listening HTTP on UNIX socket '%s'", server->unix_path); # ifdef WITH_SYSTEMD } else if (server->systemd) { - LOG_DEBUG("Binding HTTP to systemd socket ..."); - if ((RUN(ext_fd) = evhttp_my_bind_systemd(RUN(http))) < 0) { + US_LOG_DEBUG("Binding HTTP to systemd socket ..."); + if ((_RUN(ext_fd) = us_evhttp_bind_systemd(_RUN(http))) < 0) { return -1; } - LOG_INFO("Listening systemd socket ..."); + US_LOG_INFO("Listening systemd socket ..."); # endif } else { - LOG_DEBUG("Binding HTTP to [%s]:%u ...", server->host, server->port); - if (evhttp_bind_socket(RUN(http), server->host, server->port) < 0) { - LOG_PERROR("Can't bind HTTP on [%s]:%u", server->host, server->port) + US_LOG_DEBUG("Binding HTTP to [%s]:%u ...", server->host, server->port); + if (evhttp_bind_socket(_RUN(http), server->host, server->port) < 0) { + US_LOG_PERROR("Can't bind HTTP on [%s]:%u", server->host, server->port) return -1; } - LOG_INFO("Listening HTTP on [%s]:%u", server->host, server->port); + US_LOG_INFO("Listening HTTP on [%s]:%u", server->host, server->port); } return 0; } -void server_loop(server_s *server) { - LOG_INFO("Starting HTTP eventloop ..."); - event_base_dispatch(RUN(base)); - LOG_INFO("HTTP eventloop stopped"); +void us_server_loop(us_server_s *server) { + US_LOG_INFO("Starting HTTP eventloop ..."); + event_base_dispatch(_RUN(base)); + US_LOG_INFO("HTTP eventloop stopped"); } -void server_loop_break(server_s *server) { - event_base_loopbreak(RUN(base)); +void us_server_loop_break(us_server_s *server) { + event_base_loopbreak(_RUN(base)); } -#define GET_HEADER(_key) \ - evhttp_find_header(evhttp_request_get_input_headers(request), _key) +#define ADD_HEADER(x_key, x_value) assert(!evhttp_add_header(evhttp_request_get_output_headers(request), x_key, x_value)) -#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, server_s *server) { - RUN(last_request_ts) = get_now_monotonic(); +static int _http_preprocess_request(struct evhttp_request *request, us_server_s *server) { + _RUN(last_request_ts) = us_get_now_monotonic(); if (server->allow_origin[0] != '\0') { - const char *cors_headers = GET_HEADER("Access-Control-Request-Headers"); - const char *cors_method = GET_HEADER("Access-Control-Request-Method"); + const char *cors_headers = _http_get_header(request, "Access-Control-Request-Headers"); + const char *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"); @@ -240,10 +237,10 @@ static int _http_preprocess_request(struct evhttp_request *request, server_s *se return -1; } - if (RUN(auth_token)) { - const char *token = GET_HEADER("Authorization"); + if (_RUN(auth_token)) { + const char *token = _http_get_header(request, "Authorization"); - if (token == NULL || strcmp(token, RUN(auth_token)) != 0) { + if (token == NULL || strcmp(token, _RUN(auth_token)) != 0) { ADD_HEADER("WWW-Authenticate", "Basic realm=\"Restricted area\""); evhttp_send_reply(request, 401, "Unauthorized", NULL); return -1; @@ -294,7 +291,7 @@ 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) { - server_s *server = (server_s *)v_server; + us_server_s *server = (us_server_s *)v_server; PREPROCESS_REQUEST; COMPAT_REQUEST; @@ -302,7 +299,7 @@ static void _http_callback_root(struct evhttp_request *request, void *v_server) struct evbuffer *buf; assert((buf = evbuffer_new())); - assert(evbuffer_add_printf(buf, "%s", HTML_INDEX_PAGE)); + assert(evbuffer_add_printf(buf, "%s", US_HTML_INDEX_PAGE)); ADD_HEADER("Content-Type", "text/html"); evhttp_send_reply(request, HTTP_OK, "OK", buf); @@ -310,7 +307,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) { - server_s *server = (server_s *)v_server; + us_server_s *server = (us_server_s *)v_server; PREPROCESS_REQUEST; COMPAT_REQUEST; @@ -338,12 +335,12 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server assert((buf = evbuffer_new())); - if ((static_path = find_static_file_path(server->static_path, decoded_path)) == NULL) { + if ((static_path = us_find_static_file_path(server->static_path, decoded_path)) == NULL) { goto not_found; } if ((fd = open(static_path, O_RDONLY)) < 0) { - LOG_PERROR("HTTP: Can't open found static file %s", static_path); + US_LOG_PERROR("HTTP: Can't open found static file %s", static_path); goto not_found; } @@ -351,11 +348,11 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server struct stat st; if (fstat(fd, &st) < 0) { - LOG_PERROR("HTTP: Can't stat() found static file %s", static_path); + US_LOG_PERROR("HTTP: Can't stat() found static file %s", static_path); goto not_found; } if (st.st_size > 0 && evbuffer_add_file(buf, fd, 0, st.st_size) < 0) { - LOG_ERROR("HTTP: Can't serve static file %s", static_path); + US_LOG_ERROR("HTTP: Can't serve static file %s", static_path); goto not_found; } @@ -363,7 +360,7 @@ static void _http_callback_static(struct evhttp_request *request, void *v_server // and will close it when finished transferring data fd = -1; - ADD_HEADER("Content-Type", guess_mime_type(static_path)); + ADD_HEADER("Content-Type", us_guess_mime_type(static_path)); evhttp_send_reply(request, HTTP_OK, "OK", buf); goto cleanup; } @@ -397,13 +394,13 @@ 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) { - server_s *server = (server_s *)v_server; + us_server_s *server = (us_server_s *)v_server; PREPROCESS_REQUEST; - encoder_type_e enc_type; + us_encoder_type_e enc_type; unsigned enc_quality; - encoder_get_runtime_params(STREAM(enc), &enc_type, &enc_quality); + us_encoder_get_runtime_params(_STREAM(enc), &enc_type, &enc_quality); struct evbuffer *buf; assert((buf = evbuffer_new())); @@ -411,32 +408,32 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server) assert(evbuffer_add_printf(buf, "{\"ok\": true, \"result\": {" " \"encoder\": {\"type\": \"%s\", \"quality\": %u},", - encoder_type_to_string(enc_type), + us_encoder_type_to_string(enc_type), enc_quality )); - if (STREAM(run->h264)) { + if (_STREAM(run->h264)) { assert(evbuffer_add_printf(buf, " \"h264\": {\"bitrate\": %u, \"gop\": %u, \"online\": %s},", - STREAM(h264_bitrate), - STREAM(h264_gop), - bool_to_string(atomic_load(&STREAM(run->h264->online))) + _STREAM(h264_bitrate), + _STREAM(h264_gop), + us_bool_to_string(atomic_load(&_STREAM(run->h264->online))) )); } - if (STREAM(sink) || STREAM(h264_sink)) { + if (_STREAM(sink) || _STREAM(h264_sink)) { assert(evbuffer_add_printf(buf, " \"sinks\": {")); - if (STREAM(sink)) { + if (_STREAM(sink)) { assert(evbuffer_add_printf(buf, "\"jpeg\": {\"has_clients\": %s}", - bool_to_string(atomic_load(&STREAM(sink->has_clients))) + us_bool_to_string(atomic_load(&_STREAM(sink->has_clients))) )); } - if (STREAM(h264_sink)) { + if (_STREAM(h264_sink)) { assert(evbuffer_add_printf(buf, "%s\"h264\": {\"has_clients\": %s}", - (STREAM(sink) ? ", " : ""), - bool_to_string(atomic_load(&STREAM(h264_sink->has_clients))) + (_STREAM(sink) ? ", " : ""), + us_bool_to_string(atomic_load(&_STREAM(h264_sink->has_clients))) )); } assert(evbuffer_add_printf(buf, "},")); @@ -446,25 +443,25 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server) " \"source\": {\"resolution\": {\"width\": %u, \"height\": %u}," " \"online\": %s, \"desired_fps\": %u, \"captured_fps\": %u}," " \"stream\": {\"queued_fps\": %u, \"clients\": %u, \"clients_stat\": {", - (server->fake_width ? server->fake_width : EX(frame->width)), - (server->fake_height ? server->fake_height : EX(frame->height)), - bool_to_string(EX(frame->online)), - STREAM(dev->desired_fps), - EX(captured_fps), - EX(queued_fps), - RUN(stream_clients_count) + (server->fake_width ? server->fake_width : _EX(frame->width)), + (server->fake_height ? server->fake_height : _EX(frame->height)), + us_bool_to_string(_EX(frame->online)), + _STREAM(dev->desired_fps), + _EX(captured_fps), + _EX(queued_fps), + _RUN(stream_clients_count) )); - LIST_ITERATE(RUN(stream_clients), client, { + US_LIST_ITERATE(_RUN(stream_clients), client, { assert(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, client->fps, - bool_to_string(client->extra_headers), - bool_to_string(client->advance_headers), - bool_to_string(client->dual_final_frames), - bool_to_string(client->zero_data), + us_bool_to_string(client->extra_headers), + us_bool_to_string(client->advance_headers), + us_bool_to_string(client->dual_final_frames), + us_bool_to_string(client->zero_data), (client->key != NULL ? client->key : "0"), (client->next ? ", " : "") )); @@ -478,13 +475,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) { - server_s *server = (server_s *)v_server; + us_server_s *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))); + assert(!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"); @@ -492,29 +489,29 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv char header_buf[256]; -# define ADD_TIME_HEADER(_key, _value) { \ - snprintf(header_buf, 255, "%.06Lf", _value); \ - ADD_HEADER(_key, header_buf); \ +# define ADD_TIME_HEADER(x_key, x_value) { \ + snprintf(header_buf, 255, "%.06Lf", x_value); \ + ADD_HEADER(x_key, header_buf); \ } -# define ADD_UNSIGNED_HEADER(_key, _value) { \ - snprintf(header_buf, 255, "%u", _value); \ - ADD_HEADER(_key, header_buf); \ +# define ADD_UNSIGNED_HEADER(x_key, x_value) { \ + snprintf(header_buf, 255, "%u", x_value); \ + ADD_HEADER(x_key, header_buf); \ } - ADD_TIME_HEADER("X-Timestamp", get_now_real()); + ADD_TIME_HEADER("X-Timestamp", us_get_now_real()); - ADD_HEADER("X-UStreamer-Online", bool_to_string(EX(frame->online))); - ADD_UNSIGNED_HEADER("X-UStreamer-Dropped", EX(dropped)); - ADD_UNSIGNED_HEADER("X-UStreamer-Width", EX(frame->width)); - ADD_UNSIGNED_HEADER("X-UStreamer-Height", EX(frame->height)); - ADD_TIME_HEADER("X-UStreamer-Grab-Timestamp", EX(frame->grab_ts)); - ADD_TIME_HEADER("X-UStreamer-Encode-Begin-Timestamp", EX(frame->encode_begin_ts)); - ADD_TIME_HEADER("X-UStreamer-Encode-End-Timestamp", EX(frame->encode_end_ts)); - ADD_TIME_HEADER("X-UStreamer-Expose-Begin-Timestamp", EX(expose_begin_ts)); - ADD_TIME_HEADER("X-UStreamer-Expose-Cmp-Timestamp", EX(expose_cmp_ts)); - ADD_TIME_HEADER("X-UStreamer-Expose-End-Timestamp", EX(expose_end_ts)); - ADD_TIME_HEADER("X-UStreamer-Send-Timestamp", get_now_monotonic()); + ADD_HEADER("X-UStreamer-Online", us_bool_to_string(_EX(frame->online))); + ADD_UNSIGNED_HEADER("X-UStreamer-Dropped", _EX(dropped)); + ADD_UNSIGNED_HEADER("X-UStreamer-Width", _EX(frame->width)); + ADD_UNSIGNED_HEADER("X-UStreamer-Height", _EX(frame->height)); + ADD_TIME_HEADER("X-UStreamer-Grab-Timestamp", _EX(frame->grab_ts)); + ADD_TIME_HEADER("X-UStreamer-Encode-Begin-Timestamp", _EX(frame->encode_begin_ts)); + ADD_TIME_HEADER("X-UStreamer-Encode-End-Timestamp", _EX(frame->encode_end_ts)); + ADD_TIME_HEADER("X-UStreamer-Expose-Begin-Timestamp", _EX(expose_begin_ts)); + ADD_TIME_HEADER("X-UStreamer-Expose-Cmp-Timestamp", _EX(expose_cmp_ts)); + ADD_TIME_HEADER("X-UStreamer-Expose-End-Timestamp", _EX(expose_end_ts)); + ADD_TIME_HEADER("X-UStreamer-Send-Timestamp", us_get_now_monotonic()); # undef ADD_UNSUGNED_HEADER # undef ADD_TIME_HEADER @@ -534,7 +531,7 @@ 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 - server_s *server = (server_s *)v_server; + us_server_s *server = (us_server_s *)v_server; PREPROCESS_REQUEST; @@ -542,8 +539,8 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server conn = evhttp_request_get_connection(request); if (conn) { - stream_client_s *client; - A_CALLOC(client, 1); + us_stream_client_s *client; + US_CALLOC(client, 1); client->server = server; client->request = request; client->need_initial = true; @@ -551,7 +548,7 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server struct evkeyvalq params; evhttp_parse_query(evhttp_request_get_uri(request), ¶ms); -# define PARSE_PARAM(_type, _name) client->_name = uri_get_##_type(¶ms, #_name) +# define PARSE_PARAM(x_type, x_name) client->x_name = us_uri_get_##x_type(¶ms, #x_name) PARSE_PARAM(string, key); PARSE_PARAM(true, extra_headers); PARSE_PARAM(true, advance_headers); @@ -561,29 +558,29 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server evhttp_clear_headers(¶ms); client->hostport = _http_get_client_hostport(request); - client->id = get_now_id(); + client->id = us_get_now_id(); - LIST_APPEND_C(RUN(stream_clients), client, RUN(stream_clients_count)); + US_LIST_APPEND_C(_RUN(stream_clients), client, _RUN(stream_clients_count)); - if (RUN(stream_clients_count) == 1) { - atomic_store(&VID(has_clients), true); + if (_RUN(stream_clients_count) == 1) { + atomic_store(&_VID(has_clients), true); # ifdef WITH_GPIO - gpio_set_has_http_clients(true); + us_gpio_set_has_http_clients(true); # endif } - LOG_INFO("HTTP: Registered client: %s, id=%" PRIx64 "; clients now: %u", - client->hostport, client->id, RUN(stream_clients_count)); + 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); - if (server->tcp_nodelay && !RUN(ext_fd)) { + if (server->tcp_nodelay && !_RUN(ext_fd)) { evutil_socket_t fd; int on = 1; - LOG_DEBUG("HTTP: Setting up TCP_NODELAY to the client %s ...", client->hostport); + US_LOG_DEBUG("HTTP: Setting up TCP_NODELAY to the client %s ...", client->hostport); assert((fd = bufferevent_getfd(buf_event)) >= 0); if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)) != 0) { - LOG_PERROR("HTTP: Can't set TCP_NODELAY to the client %s", client->hostport); + US_LOG_PERROR("HTTP: Can't set TCP_NODELAY to the client %s", client->hostport); } } bufferevent_setcb(buf_event, NULL, NULL, _http_callback_stream_error, (void *)client); @@ -598,12 +595,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" - stream_client_s *client = (stream_client_s *)v_client; - struct evhttp_request *request = client->request; // for GET_HEADER - server_s *server = client->server; + us_stream_client_s *client = (us_stream_client_s *)v_client; + us_server_s *server = client->server; - long double now = get_now_monotonic(); - long long now_second = floor_ms(now); + long double now = us_get_now_monotonic(); + long long now_second = us_floor_ms(now); if (now_second != client->fps_accum_second) { client->fps = client->fps_accum; @@ -636,14 +632,14 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c # define ADD_ADVANCE_HEADERS \ assert(evbuffer_add_printf(buf, \ - "Content-Type: image/jpeg" RN "X-Timestamp: %.06Lf" RN RN, get_now_real())) + "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)); if (client->server->allow_origin[0] != '\0') { - const char *cors_headers = GET_HEADER("Access-Control-Request-Headers"); - const char *cors_method = GET_HEADER("Access-Control-Request-Method"); + 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"); assert(evbuffer_add_printf(buf, "Access-Control-Allow-Origin: %s" RN @@ -684,8 +680,8 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c "Content-Length: %zu" RN "X-Timestamp: %.06Lf" RN "%s", - (!client->zero_data ? EX(frame->used) : 0), - get_now_real(), + (!client->zero_data ? _EX(frame->used) : 0), + us_get_now_real(), (client->extra_headers ? "" : RN) )); if (client->extra_headers) { @@ -704,25 +700,25 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c "X-UStreamer-Send-Time: %.06Lf" RN "X-UStreamer-Latency: %.06Lf" RN RN, - bool_to_string(EX(frame->online)), - EX(dropped), - EX(frame->width), - EX(frame->height), + us_bool_to_string(_EX(frame->online)), + _EX(dropped), + _EX(frame->width), + _EX(frame->height), client->fps, - EX(frame->grab_ts), - EX(frame->encode_begin_ts), - EX(frame->encode_end_ts), - EX(expose_begin_ts), - EX(expose_cmp_ts), - EX(expose_end_ts), + _EX(frame->grab_ts), + _EX(frame->encode_begin_ts), + _EX(frame->encode_end_ts), + _EX(expose_begin_ts), + _EX(expose_cmp_ts), + _EX(expose_end_ts), now, - now - EX(frame->grab_ts) + now - _EX(frame->grab_ts) )); } } if (!client->zero_data) { - assert(!evbuffer_add(buf, (void *)EX(frame->data), EX(frame->used))); + assert(!evbuffer_add(buf, (void *)_EX(frame->data), _EX(frame->used))); } assert(evbuffer_add_printf(buf, RN "--" BOUNDARY RN)); @@ -741,21 +737,21 @@ 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) { - stream_client_s *client = (stream_client_s *)v_client; - server_s *server = client->server; + us_stream_client_s *client = (us_stream_client_s *)v_client; + us_server_s *server = client->server; - LIST_REMOVE_C(RUN(stream_clients), client, RUN(stream_clients_count)); + US_LIST_REMOVE_C(_RUN(stream_clients), client, _RUN(stream_clients_count)); - if (RUN(stream_clients_count) == 0) { - atomic_store(&VID(has_clients), false); + if (_RUN(stream_clients_count) == 0) { + atomic_store(&_VID(has_clients), false); # ifdef WITH_GPIO - gpio_set_has_http_clients(false); + us_gpio_set_has_http_clients(false); # endif } - char *reason = bufferevent_my_format_reason(what); - LOG_INFO("HTTP: Disconnected client: %s, id=%" PRIx64 ", %s; clients now: %u", - client->hostport, client->id, reason, RUN(stream_clients_count)); + char *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); @@ -768,11 +764,11 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN free(client); } -static void _http_queue_send_stream(server_s *server, bool stream_updated, bool frame_updated) { +static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bool frame_updated) { bool has_clients = false; bool queued = false; - LIST_ITERATE(RUN(stream_clients), client, { + US_LIST_ITERATE(_RUN(stream_clients), client, { struct evhttp_connection *conn = evhttp_request_get_connection(client->request); if (conn) { // Фикс для бага WebKit. При включенной опции дропа одинаковых фреймов, @@ -808,45 +804,45 @@ static void _http_queue_send_stream(server_s *server, bool stream_updated, bool if (queued) { static unsigned queued_fps_accum = 0; static long long queued_fps_second = 0; - long long now = floor_ms(get_now_monotonic()); + long long now = us_floor_ms(us_get_now_monotonic()); if (now != queued_fps_second) { - EX(queued_fps) = queued_fps_accum; + _EX(queued_fps) = queued_fps_accum; queued_fps_accum = 0; queued_fps_second = now; } queued_fps_accum += 1; } else if (!has_clients) { - EX(queued_fps) = 0; + _EX(queued_fps) = 0; } } static void _http_request_watcher(UNUSED int fd, UNUSED short what, void *v_server) { - server_s *server = (server_s *)v_server; - const long double now = get_now_monotonic(); + us_server_s *server = (us_server_s *)v_server; + const long double now = us_get_now_monotonic(); - if (stream_has_clients(RUN(stream))) { - RUN(last_request_ts) = now; - } else if (RUN(last_request_ts) + server->exit_on_no_clients < now) { - LOG_INFO("HTTP: No requests or HTTP/sink clients found in last %u seconds, exiting ...", + if (us_stream_has_clients(_RUN(stream))) { + _RUN(last_request_ts) = now; + } else if (_RUN(last_request_ts) + server->exit_on_no_clients < now) { + US_LOG_INFO("HTTP: No requests or HTTP/sink clients found in last %u seconds, exiting ...", server->exit_on_no_clients); - process_suicide(); - RUN(last_request_ts) = now; + us_process_suicide(); + _RUN(last_request_ts) = now; } } static void _http_refresher(UNUSED int fd, UNUSED short what, void *v_server) { - server_s *server = (server_s *)v_server; + us_server_s *server = (us_server_s *)v_server; bool stream_updated = false; bool frame_updated = false; - if (atomic_load(&VID(updated))) { + if (atomic_load(&_VID(updated))) { frame_updated = _expose_new_frame(server); stream_updated = true; - } else if (EX(expose_end_ts) + 1 < get_now_monotonic()) { - LOG_DEBUG("HTTP: Repeating exposed ..."); - EX(expose_begin_ts) = get_now_monotonic(); - EX(expose_cmp_ts) = EX(expose_begin_ts); - EX(expose_end_ts) = EX(expose_begin_ts); + } else if (_EX(expose_end_ts) + 1 < us_get_now_monotonic()) { + US_LOG_DEBUG("HTTP: Repeating exposed ..."); + _EX(expose_begin_ts) = us_get_now_monotonic(); + _EX(expose_cmp_ts) = _EX(expose_begin_ts); + _EX(expose_end_ts) = _EX(expose_begin_ts); frame_updated = true; stream_updated = true; } @@ -857,68 +853,67 @@ static void _http_refresher(UNUSED int fd, UNUSED short what, void *v_server) { frame_updated && server->notify_parent && ( - EX(notify_last_online) != EX(frame->online) - || EX(notify_last_width) != EX(frame->width) - || EX(notify_last_height) != EX(frame->height) + _EX(notify_last_online) != _EX(frame->online) + || _EX(notify_last_width) != _EX(frame->width) + || _EX(notify_last_height) != _EX(frame->height) ) ) { - EX(notify_last_online) = EX(frame->online); - EX(notify_last_width) = EX(frame->width); - EX(notify_last_height) = EX(frame->height); - process_notify_parent(); + _EX(notify_last_online) = _EX(frame->online); + _EX(notify_last_width) = _EX(frame->width); + _EX(notify_last_height) = _EX(frame->height); + us_process_notify_parent(); } } -static bool _expose_new_frame(server_s *server) { +static bool _expose_new_frame(us_server_s *server) { bool updated = false; - A_MUTEX_LOCK(&VID(mutex)); + US_MUTEX_LOCK(&_VID(mutex)); - LOG_DEBUG("HTTP: Updating exposed frame (online=%d) ...", VID(frame->online)); + US_LOG_DEBUG("HTTP: Updating exposed frame (online=%d) ...", _VID(frame->online)); - EX(captured_fps) = VID(captured_fps); - EX(expose_begin_ts) = get_now_monotonic(); + _EX(captured_fps) = _VID(captured_fps); + _EX(expose_begin_ts) = us_get_now_monotonic(); - if (server->drop_same_frames && VID(frame->online)) { + if (server->drop_same_frames && _VID(frame->online)) { bool need_drop = false; bool maybe_same = false; if ( - (need_drop = (EX(dropped) < server->drop_same_frames)) - && (maybe_same = frame_compare(EX(frame), VID(frame))) + (need_drop = (_EX(dropped) < server->drop_same_frames)) + && (maybe_same = us_frame_compare(_EX(frame), _VID(frame))) ) { - EX(expose_cmp_ts) = get_now_monotonic(); - EX(expose_end_ts) = EX(expose_cmp_ts); - LOG_VERBOSE("HTTP: Dropped same frame number %u; cmp_time=%.06Lf", - EX(dropped), EX(expose_cmp_ts) - EX(expose_begin_ts)); - EX(dropped) += 1; + _EX(expose_cmp_ts) = us_get_now_monotonic(); + _EX(expose_end_ts) = _EX(expose_cmp_ts); + US_LOG_VERBOSE("HTTP: Dropped same frame number %u; cmp_time=%.06Lf", + _EX(dropped), _EX(expose_cmp_ts) - _EX(expose_begin_ts)); + _EX(dropped) += 1; goto not_updated; } else { - EX(expose_cmp_ts) = get_now_monotonic(); - LOG_VERBOSE("HTTP: Passed same frame check (need_drop=%d, maybe_same=%d); cmp_time=%.06Lf", - need_drop, maybe_same, (EX(expose_cmp_ts) - EX(expose_begin_ts))); + _EX(expose_cmp_ts) = us_get_now_monotonic(); + US_LOG_VERBOSE("HTTP: Passed same frame check (need_drop=%d, maybe_same=%d); cmp_time=%.06Lf", + need_drop, maybe_same, (_EX(expose_cmp_ts) - _EX(expose_begin_ts))); } } - frame_copy(VID(frame), EX(frame)); + us_frame_copy(_VID(frame), _EX(frame)); - EX(dropped) = 0; - EX(expose_cmp_ts) = EX(expose_begin_ts); - EX(expose_end_ts) = get_now_monotonic(); + _EX(dropped) = 0; + _EX(expose_cmp_ts) = _EX(expose_begin_ts); + _EX(expose_end_ts) = us_get_now_monotonic(); - LOG_VERBOSE("HTTP: Exposed frame: online=%d, exp_time=%.06Lf", - EX(frame->online), EX(expose_end_ts) - EX(expose_begin_ts)); + US_LOG_VERBOSE("HTTP: Exposed frame: online=%d, exp_time=%.06Lf", + _EX(frame->online), _EX(expose_end_ts) - _EX(expose_begin_ts)); updated = true; not_updated: - atomic_store(&VID(updated), false); - A_MUTEX_UNLOCK(&VID(mutex)); + atomic_store(&_VID(updated), false); + US_MUTEX_UNLOCK(&_VID(mutex)); return updated; } -#undef EX -#undef VID -#undef STREAM -#undef RUN +static const char *_http_get_header(struct evhttp_request *request, const char *key) { + return evhttp_find_header(evhttp_request_get_input_headers(request), key); +} static char *_http_get_client_hostport(struct evhttp_request *request) { char *addr = NULL; @@ -930,7 +925,7 @@ static char *_http_get_client_hostport(struct evhttp_request *request) { assert(addr = strdup(peer)); } - const char *xff = GET_HEADER("X-Forwarded-For"); + const char *xff = _http_get_header(request, "X-Forwarded-For"); if (xff) { if (addr) { free(addr); @@ -949,9 +944,7 @@ static char *_http_get_client_hostport(struct evhttp_request *request) { } char *hostport; - A_ASPRINTF(hostport, "[%s]:%u", addr, port); + US_ASPRINTF(hostport, "[%s]:%u", addr, port); free(addr); return hostport; } - -#undef GET_HEADER diff --git a/src/ustreamer/http/server.h b/src/ustreamer/http/server.h index 9b122ae..2f5809f 100644 --- a/src/ustreamer/http/server.h +++ b/src/ustreamer/http/server.h @@ -76,30 +76,30 @@ #endif -typedef struct stream_client_sx { - struct server_sx *server; - struct evhttp_request *request; +typedef struct us_stream_client_sx { + struct us_server_sx *server; + struct evhttp_request *request; - char *key; - bool extra_headers; - bool advance_headers; - bool dual_final_frames; - bool zero_data; + char *key; + bool extra_headers; + bool advance_headers; + bool dual_final_frames; + bool zero_data; - char *hostport; - uint64_t id; - bool need_initial; - bool need_first_frame; - bool updated_prev; - unsigned fps; - unsigned fps_accum; - long long fps_accum_second; + char *hostport; + uint64_t id; + bool need_initial; + bool need_first_frame; + bool updated_prev; + unsigned fps; + unsigned fps_accum; + long long fps_accum_second; - LIST_STRUCT(struct stream_client_sx); -} stream_client_s; + US_LIST_STRUCT(struct us_stream_client_sx); +} us_stream_client_s; typedef struct { - frame_s *frame; + us_frame_s *frame; unsigned captured_fps; unsigned queued_fps; unsigned dropped; @@ -107,10 +107,10 @@ typedef struct { long double expose_cmp_ts; long double expose_end_ts; - bool notify_last_online; - unsigned notify_last_width; - unsigned notify_last_height; -} exposed_s; + bool notify_last_online; + unsigned notify_last_width; + unsigned notify_last_height; +} us_exposed_s; typedef struct { struct event_base *base; @@ -123,14 +123,14 @@ typedef struct { long double last_request_ts; struct event *refresher; - stream_s *stream; - exposed_s *exposed; + us_stream_s *stream; + us_exposed_s *exposed; - stream_client_s *stream_clients; + us_stream_client_s *stream_clients; unsigned stream_clients_count; -} server_runtime_s; +} us_server_runtime_s; -typedef struct server_sx { +typedef struct us_server_sx { char *host; unsigned port; @@ -157,13 +157,13 @@ typedef struct server_sx { bool notify_parent; unsigned exit_on_no_clients; - server_runtime_s *run; -} server_s; + us_server_runtime_s *run; +} us_server_s; -server_s *server_init(stream_s *stream); -void server_destroy(server_s *server); +us_server_s *us_server_init(us_stream_s *stream); +void us_server_destroy(us_server_s *server); -int server_listen(server_s *server); -void server_loop(server_s *server); -void server_loop_break(server_s *server); +int us_server_listen(us_server_s *server); +void us_server_loop(us_server_s *server); +void us_server_loop_break(us_server_s *server); diff --git a/src/ustreamer/http/static.c b/src/ustreamer/http/static.c index 7902f1e..01dd301 100644 --- a/src/ustreamer/http/static.c +++ b/src/ustreamer/http/static.c @@ -23,29 +23,29 @@ #include "static.h" -char *find_static_file_path(const char *root_path, const char *request_path) { +char *us_find_static_file_path(const char *root_path, const char *request_path) { char *path = NULL; - char *simplified_path = simplify_request_path(request_path); + char *simplified_path = us_simplify_request_path(request_path); if (simplified_path[0] == '\0') { - LOG_VERBOSE("HTTP: Invalid request path %s to static", request_path); + US_LOG_VERBOSE("HTTP: Invalid request path %s to static", request_path); goto error; } - A_CALLOC(path, strlen(root_path) + strlen(simplified_path) + 16); // + reserved for /index.html + US_CALLOC(path, strlen(root_path) + strlen(simplified_path) + 16); // + reserved for /index.html sprintf(path, "%s/%s", root_path, simplified_path); struct stat st; # define LOAD_STAT { \ if (lstat(path, &st) < 0) { \ - LOG_VERBOSE_PERROR("HTTP: Can't stat() static path %s", path); \ + US_LOG_VERBOSE_PERROR("HTTP: Can't stat() static path %s", path); \ goto error; \ } \ } LOAD_STAT; if (S_ISDIR(st.st_mode)) { - LOG_VERBOSE("HTTP: Requested static path %s is a directory, trying %s/index.html", path, path); + US_LOG_VERBOSE("HTTP: Requested static path %s is a directory, trying %s/index.html", path, path); strcat(path, "/index.html"); LOAD_STAT; } @@ -53,12 +53,12 @@ char *find_static_file_path(const char *root_path, const char *request_path) { # undef LOAD_STAT if (!S_ISREG(st.st_mode)) { - LOG_VERBOSE("HTTP: Not a regular file: %s", path); + US_LOG_VERBOSE("HTTP: Not a regular file: %s", path); goto error; } if (access(path, R_OK) < 0) { - LOG_VERBOSE_PERROR("HTTP: Can't access() R_OK file %s", path); + US_LOG_VERBOSE_PERROR("HTTP: Can't access() R_OK file %s", path); goto error; } diff --git a/src/ustreamer/http/static.h b/src/ustreamer/http/static.h index c6b7734..62ed72c 100644 --- a/src/ustreamer/http/static.h +++ b/src/ustreamer/http/static.h @@ -35,4 +35,4 @@ #include "path.h" -char *find_static_file_path(const char *root_path, const char *request_path); +char *us_find_static_file_path(const char *root_path, const char *request_path); diff --git a/src/ustreamer/http/systemd/systemd.c b/src/ustreamer/http/systemd/systemd.c index d006ff5..eb6ea33 100644 --- a/src/ustreamer/http/systemd/systemd.c +++ b/src/ustreamer/http/systemd/systemd.c @@ -23,10 +23,10 @@ #include "systemd.h" -evutil_socket_t evhttp_my_bind_systemd(struct evhttp *http) { +evutil_socket_t us_evhttp_bind_systemd(struct evhttp *http) { int fds = sd_listen_fds(1); if (fds < 1) { - LOG_ERROR("No available systemd sockets"); + US_LOG_ERROR("No available systemd sockets"); return -1; } @@ -39,7 +39,7 @@ evutil_socket_t evhttp_my_bind_systemd(struct evhttp *http) { assert(!evutil_make_socket_nonblocking(fd)); if (evhttp_accept_socket(http, fd) < 0) { - LOG_PERROR("Can't evhttp_accept_socket() systemd socket"); + US_LOG_PERROR("Can't evhttp_accept_socket() systemd socket"); return -1; } return fd; diff --git a/src/ustreamer/http/systemd/systemd.h b/src/ustreamer/http/systemd/systemd.h index 6494cb3..60a02b5 100644 --- a/src/ustreamer/http/systemd/systemd.h +++ b/src/ustreamer/http/systemd/systemd.h @@ -34,4 +34,4 @@ #include "../../../libs/logging.h" -evutil_socket_t evhttp_my_bind_systemd(struct evhttp *http); +evutil_socket_t us_evhttp_bind_systemd(struct evhttp *http); diff --git a/src/ustreamer/http/unix.c b/src/ustreamer/http/unix.c index fa855f8..3f34e66 100644 --- a/src/ustreamer/http/unix.c +++ b/src/ustreamer/http/unix.c @@ -23,13 +23,13 @@ #include "unix.h" -evutil_socket_t evhttp_my_bind_unix(struct evhttp *http, const char *path, bool rm, mode_t mode) { +evutil_socket_t us_evhttp_bind_unix(struct evhttp *http, const char *path, bool rm, mode_t mode) { struct sockaddr_un addr = {0}; # define MAX_SUN_PATH (sizeof(addr.sun_path) - 1) if (strlen(path) > MAX_SUN_PATH) { - LOG_ERROR("UNIX socket path is too long; max=%zu", MAX_SUN_PATH); + US_LOG_ERROR("UNIX socket path is too long; max=%zu", MAX_SUN_PATH); return -1; } @@ -44,24 +44,24 @@ evutil_socket_t evhttp_my_bind_unix(struct evhttp *http, const char *path, bool if (rm && unlink(path) < 0) { if (errno != ENOENT) { - LOG_PERROR("Can't remove old UNIX socket '%s'", path); + US_LOG_PERROR("Can't remove old UNIX socket '%s'", path); return -1; } } if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { - LOG_PERROR("Can't bind HTTP to UNIX socket '%s'", path); + US_LOG_PERROR("Can't bind HTTP to UNIX socket '%s'", path); return -1; } if (mode && chmod(path, mode) < 0) { - LOG_PERROR("Can't set permissions %o to UNIX socket '%s'", mode, path); + US_LOG_PERROR("Can't set permissions %o to UNIX socket '%s'", mode, path); return -1; } if (listen(fd, 128) < 0) { - LOG_PERROR("Can't listen UNIX socket '%s'", path); + US_LOG_PERROR("Can't listen UNIX socket '%s'", path); return -1; } if (evhttp_accept_socket(http, fd) < 0) { - LOG_PERROR("Can't evhttp_accept_socket() UNIX socket '%s'", path); + US_LOG_PERROR("Can't evhttp_accept_socket() UNIX socket '%s'", path); return -1; } return fd; diff --git a/src/ustreamer/http/unix.h b/src/ustreamer/http/unix.h index 29f9ec2..9a3ae34 100644 --- a/src/ustreamer/http/unix.h +++ b/src/ustreamer/http/unix.h @@ -39,4 +39,4 @@ #include "../../libs/logging.h" -evutil_socket_t evhttp_my_bind_unix(struct evhttp *http, const char *path, bool rm, mode_t mode); +evutil_socket_t us_evhttp_bind_unix(struct evhttp *http, const char *path, bool rm, mode_t mode); diff --git a/src/ustreamer/http/uri.c b/src/ustreamer/http/uri.c index 24ed0c4..4ce5ecb 100644 --- a/src/ustreamer/http/uri.c +++ b/src/ustreamer/http/uri.c @@ -23,7 +23,7 @@ #include "uri.h" -bool uri_get_true(struct evkeyvalq *params, const char *key) { +bool us_uri_get_true(struct evkeyvalq *params, const char *key) { const char *value_str = evhttp_find_header(params, key); if (value_str != NULL) { if ( @@ -37,7 +37,7 @@ bool uri_get_true(struct evkeyvalq *params, const char *key) { return false; } -char *uri_get_string(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); if (value_str != NULL) { return evhttp_encode_uri(value_str); diff --git a/src/ustreamer/http/uri.h b/src/ustreamer/http/uri.h index 1fe225d..f559622 100644 --- a/src/ustreamer/http/uri.h +++ b/src/ustreamer/http/uri.h @@ -29,5 +29,5 @@ #include -bool uri_get_true(struct evkeyvalq *params, const char *key); -char *uri_get_string(struct evkeyvalq *params, const char *key); +bool us_uri_get_true(struct evkeyvalq *params, const char *key); +char *us_uri_get_string(struct evkeyvalq *params, const char *key); diff --git a/src/ustreamer/m2m.c b/src/ustreamer/m2m.c index d1ab1e2..0a92933 100644 --- a/src/ustreamer/m2m.c +++ b/src/ustreamer/m2m.c @@ -23,29 +23,31 @@ #include "m2m.h" -static m2m_encoder_s *_m2m_encoder_init( +static us_m2m_encoder_s *_m2m_encoder_init( const char *name, const char *path, unsigned output_format, unsigned fps, unsigned bitrate, unsigned gop, unsigned quality, bool allow_dma); -static void _m2m_encoder_prepare(m2m_encoder_s *enc, const frame_s *frame); +static void _m2m_encoder_prepare(us_m2m_encoder_s *enc, const us_frame_s *frame); static int _m2m_encoder_init_buffers( - m2m_encoder_s *enc, const char *name, enum v4l2_buf_type type, - m2m_buffer_s **bufs_ptr, unsigned *n_bufs_ptr, bool dma); + us_m2m_encoder_s *enc, const char *name, enum v4l2_buf_type type, + us_m2m_buffer_s **bufs_ptr, unsigned *n_bufs_ptr, bool dma); -static void _m2m_encoder_cleanup(m2m_encoder_s *enc); +static void _m2m_encoder_cleanup(us_m2m_encoder_s *enc); -static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key); +static int _m2m_encoder_compress_raw(us_m2m_encoder_s *enc, const us_frame_s *src, us_frame_s *dest, bool force_key); -#define E_LOG_ERROR(_msg, ...) LOG_ERROR("%s: " _msg, enc->name, ##__VA_ARGS__) -#define E_LOG_PERROR(_msg, ...) LOG_PERROR("%s: " _msg, enc->name, ##__VA_ARGS__) -#define E_LOG_INFO(_msg, ...) LOG_INFO("%s: " _msg, enc->name, ##__VA_ARGS__) -#define E_LOG_VERBOSE(_msg, ...) LOG_VERBOSE("%s: " _msg, enc->name, ##__VA_ARGS__) -#define E_LOG_DEBUG(_msg, ...) LOG_DEBUG("%s: " _msg, enc->name, ##__VA_ARGS__) +#define _E_LOG_ERROR(x_msg, ...) US_LOG_ERROR("%s: " x_msg, enc->name, ##__VA_ARGS__) +#define _E_LOG_PERROR(x_msg, ...) US_LOG_PERROR("%s: " x_msg, enc->name, ##__VA_ARGS__) +#define _E_LOG_INFO(x_msg, ...) US_LOG_INFO("%s: " x_msg, enc->name, ##__VA_ARGS__) +#define _E_LOG_VERBOSE(x_msg, ...) US_LOG_VERBOSE("%s: " x_msg, enc->name, ##__VA_ARGS__) +#define _E_LOG_DEBUG(x_msg, ...) US_LOG_DEBUG("%s: " x_msg, enc->name, ##__VA_ARGS__) + +#define _RUN(x_next) enc->run->x_next -m2m_encoder_s *m2m_h264_encoder_init(const char *name, const char *path, unsigned bitrate, unsigned gop) { +us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, unsigned bitrate, unsigned gop) { // FIXME: 30 or 0? https://github.com/6by9/yavta/blob/master/yavta.c#L2100 // По логике вещей правильно 0, но почему-то на низких разрешениях типа 640x480 // енкодер через несколько секунд перестает производить корректные фреймы. @@ -53,7 +55,7 @@ m2m_encoder_s *m2m_h264_encoder_init(const char *name, const char *path, unsigne return _m2m_encoder_init(name, path, V4L2_PIX_FMT_H264, 30, bitrate, gop, 0, true); } -m2m_encoder_s *m2m_mjpeg_encoder_init(const char *name, const char *path, unsigned quality) { +us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, unsigned quality) { const double b_min = 25; const double b_max = 20000; const double step = 25; @@ -65,67 +67,65 @@ m2m_encoder_s *m2m_mjpeg_encoder_init(const char *name, const char *path, unsign return _m2m_encoder_init(name, path, V4L2_PIX_FMT_MJPEG, 30, bitrate, 0, 0, true); } -m2m_encoder_s *m2m_jpeg_encoder_init(const char *name, const char *path, unsigned quality) { +us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, unsigned quality) { // FIXME: DMA не работает return _m2m_encoder_init(name, path, V4L2_PIX_FMT_JPEG, 30, 0, 0, quality, false); } -void m2m_encoder_destroy(m2m_encoder_s *enc) { - E_LOG_INFO("Destroying encoder ..."); +void us_m2m_encoder_destroy(us_m2m_encoder_s *enc) { + _E_LOG_INFO("Destroying encoder ..."); _m2m_encoder_cleanup(enc); free(enc->path); free(enc->name); free(enc); } -#define RUN(_next) enc->run->_next - -int m2m_encoder_compress(m2m_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key) { - frame_encoding_begin(src, dest, (enc->output_format == V4L2_PIX_FMT_MJPEG ? V4L2_PIX_FMT_JPEG : enc->output_format)); +int us_m2m_encoder_compress(us_m2m_encoder_s *enc, const us_frame_s *src, us_frame_s *dest, bool force_key) { + us_frame_encoding_begin(src, dest, (enc->output_format == V4L2_PIX_FMT_MJPEG ? V4L2_PIX_FMT_JPEG : enc->output_format)); if ( - RUN(width) != src->width - || RUN(height) != src->height - || RUN(input_format) != src->format - || RUN(stride) != src->stride - || RUN(dma) != (enc->allow_dma && src->dma_fd >= 0) + _RUN(width) != src->width + || _RUN(height) != src->height + || _RUN(input_format) != src->format + || _RUN(stride) != src->stride + || _RUN(dma) != (enc->allow_dma && src->dma_fd >= 0) ) { _m2m_encoder_prepare(enc, src); } - if (!RUN(ready)) { // Already prepared but failed + if (!_RUN(ready)) { // Already prepared but failed return -1; } - force_key = (enc->output_format == V4L2_PIX_FMT_H264 && (force_key || RUN(last_online) != src->online)); + force_key = (enc->output_format == V4L2_PIX_FMT_H264 && (force_key || _RUN(last_online) != src->online)); if (_m2m_encoder_compress_raw(enc, src, dest, force_key) < 0) { _m2m_encoder_cleanup(enc); - E_LOG_ERROR("Encoder destroyed due an error (compress)"); + _E_LOG_ERROR("Encoder destroyed due an error (compress)"); return -1; } - frame_encoding_end(dest); + us_frame_encoding_end(dest); - E_LOG_VERBOSE("Compressed new frame: size=%zu, time=%0.3Lf, force_key=%d", + _E_LOG_VERBOSE("Compressed new frame: size=%zu, time=%0.3Lf, force_key=%d", dest->used, dest->encode_end_ts - dest->encode_begin_ts, force_key); - RUN(last_online) = src->online; + _RUN(last_online) = src->online; return 0; } -static m2m_encoder_s *_m2m_encoder_init( +static us_m2m_encoder_s *_m2m_encoder_init( const char *name, const char *path, unsigned output_format, unsigned fps, unsigned bitrate, unsigned gop, unsigned quality, bool allow_dma) { - LOG_INFO("%s: Initializing encoder ...", name); + US_LOG_INFO("%s: Initializing encoder ...", name); - m2m_encoder_runtime_s *run; - A_CALLOC(run, 1); + us_m2m_encoder_runtime_s *run; + US_CALLOC(run, 1); run->last_online = -1; run->fd = -1; - m2m_encoder_s *enc; - A_CALLOC(enc, 1); + us_m2m_encoder_s *enc; + US_CALLOC(enc, 1); assert(enc->name = strdup(name)); if (path == NULL) { assert(enc->path = strdup(output_format == V4L2_PIX_FMT_JPEG ? "/dev/video31" : "/dev/video11")); @@ -142,45 +142,45 @@ static m2m_encoder_s *_m2m_encoder_init( return enc; } -#define E_XIOCTL(_request, _value, _msg, ...) { \ - if (xioctl(RUN(fd), _request, _value) < 0) { \ - E_LOG_PERROR(_msg, ##__VA_ARGS__); \ +#define _E_XIOCTL(x_request, x_value, x_msg, ...) { \ + if (us_xioctl(_RUN(fd), x_request, x_value) < 0) { \ + _E_LOG_PERROR(x_msg, ##__VA_ARGS__); \ goto error; \ } \ } -static void _m2m_encoder_prepare(m2m_encoder_s *enc, const frame_s *frame) { +static void _m2m_encoder_prepare(us_m2m_encoder_s *enc, const us_frame_s *frame) { bool dma = (enc->allow_dma && frame->dma_fd >= 0); - E_LOG_INFO("Configuring encoder: DMA=%d ...", dma); + _E_LOG_INFO("Configuring encoder: DMA=%d ...", dma); _m2m_encoder_cleanup(enc); - RUN(width) = frame->width; - RUN(height) = frame->height; - RUN(input_format) = frame->format; - RUN(stride) = frame->stride; - RUN(dma) = dma; + _RUN(width) = frame->width; + _RUN(height) = frame->height; + _RUN(input_format) = frame->format; + _RUN(stride) = frame->stride; + _RUN(dma) = dma; - if ((RUN(fd) = open(enc->path, O_RDWR)) < 0) { - E_LOG_PERROR("Can't open encoder device"); + if ((_RUN(fd) = open(enc->path, O_RDWR)) < 0) { + _E_LOG_PERROR("Can't open encoder device"); goto error; } - E_LOG_DEBUG("Encoder device fd=%d opened", RUN(fd)); + _E_LOG_DEBUG("Encoder device fd=%d opened", _RUN(fd)); -# define SET_OPTION(_cid, _value) { \ - struct v4l2_control _ctl = {0}; \ - _ctl.id = _cid; \ - _ctl.value = _value; \ - E_LOG_DEBUG("Configuring option " #_cid " ..."); \ - E_XIOCTL(VIDIOC_S_CTRL, &_ctl, "Can't set option " #_cid); \ +# define SET_OPTION(x_cid, x_value) { \ + struct v4l2_control m_ctl = {0}; \ + m_ctl.id = x_cid; \ + m_ctl.value = x_value; \ + _E_LOG_DEBUG("Configuring option " #x_cid " ..."); \ + _E_XIOCTL(VIDIOC_S_CTRL, &m_ctl, "Can't set option " #x_cid); \ } if (enc->output_format == V4L2_PIX_FMT_H264) { SET_OPTION(V4L2_CID_MPEG_VIDEO_BITRATE, enc->bitrate); SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, enc->gop); SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE); - if (RUN(width) * RUN(height) <= 1920 * 1080) { // https://forums.raspberrypi.com/viewtopic.php?t=291447#p1762296 + if (_RUN(width) * _RUN(height) <= 1920 * 1080) { // https://forums.raspberrypi.com/viewtopic.php?t=291447#p1762296 SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); } else { SET_OPTION(V4L2_CID_MPEG_VIDEO_H264_LEVEL, V4L2_MPEG_VIDEO_H264_LEVEL_5_1); @@ -199,35 +199,35 @@ static void _m2m_encoder_prepare(m2m_encoder_s *enc, const frame_s *frame) { { struct v4l2_format fmt = {0}; fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.width = RUN(width); - fmt.fmt.pix_mp.height = RUN(height); - fmt.fmt.pix_mp.pixelformat = RUN(input_format); + fmt.fmt.pix_mp.width = _RUN(width); + fmt.fmt.pix_mp.height = _RUN(height); + fmt.fmt.pix_mp.pixelformat = _RUN(input_format); fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_JPEG; // libcamera currently has no means to request the right colour space fmt.fmt.pix_mp.num_planes = 1; - // fmt.fmt.pix_mp.plane_fmt[0].bytesperline = RUN(stride); - E_LOG_DEBUG("Configuring INPUT format ..."); - E_XIOCTL(VIDIOC_S_FMT, &fmt, "Can't set INPUT format"); + // fmt.fmt.pix_mp.plane_fmt[0].bytesperline = _RUN(stride); + _E_LOG_DEBUG("Configuring INPUT format ..."); + _E_XIOCTL(VIDIOC_S_FMT, &fmt, "Can't set INPUT format"); } { struct v4l2_format fmt = {0}; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.width = RUN(width); - fmt.fmt.pix_mp.height = RUN(height); + fmt.fmt.pix_mp.width = _RUN(width); + fmt.fmt.pix_mp.height = _RUN(height); fmt.fmt.pix_mp.pixelformat = enc->output_format; fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; fmt.fmt.pix_mp.num_planes = 1; // fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 0; // fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 512 << 10; - E_LOG_DEBUG("Configuring OUTPUT format ..."); - E_XIOCTL(VIDIOC_S_FMT, &fmt, "Can't set OUTPUT format"); + _E_LOG_DEBUG("Configuring OUTPUT format ..."); + _E_XIOCTL(VIDIOC_S_FMT, &fmt, "Can't set OUTPUT format"); if (fmt.fmt.pix_mp.pixelformat != enc->output_format) { char fourcc_str[8]; - E_LOG_ERROR("The OUTPUT format can't be configured as %s", - fourcc_to_string(enc->output_format, fourcc_str, 8)); - E_LOG_ERROR("In case of Raspberry Pi, try to append 'start_x=1' to /boot/config.txt"); + _E_LOG_ERROR("The OUTPUT format can't be configured as %s", + us_fourcc_to_string(enc->output_format, fourcc_str, 8)); + _E_LOG_ERROR("In case of Raspberry Pi, try to append 'start_x=1' to /boot/config.txt"); goto error; } } @@ -237,61 +237,61 @@ static void _m2m_encoder_prepare(m2m_encoder_s *enc, const frame_s *frame) { setfps.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; setfps.parm.output.timeperframe.numerator = 1; setfps.parm.output.timeperframe.denominator = enc->fps; - E_LOG_DEBUG("Configuring INPUT FPS ..."); - E_XIOCTL(VIDIOC_S_PARM, &setfps, "Can't set INPUT FPS"); + _E_LOG_DEBUG("Configuring INPUT FPS ..."); + _E_XIOCTL(VIDIOC_S_PARM, &setfps, "Can't set INPUT FPS"); } if (_m2m_encoder_init_buffers(enc, (dma ? "INPUT-DMA" : "INPUT"), V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - &RUN(input_bufs), &RUN(n_input_bufs), dma) < 0) { + &_RUN(input_bufs), &_RUN(n_input_bufs), dma) < 0) { goto error; } if (_m2m_encoder_init_buffers(enc, "OUTPUT", V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - &RUN(output_bufs), &RUN(n_output_bufs), false) < 0) { + &_RUN(output_bufs), &_RUN(n_output_bufs), false) < 0) { goto error; } { enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - E_LOG_DEBUG("Starting INPUT ..."); - E_XIOCTL(VIDIOC_STREAMON, &type, "Can't start INPUT"); + _E_LOG_DEBUG("Starting INPUT ..."); + _E_XIOCTL(VIDIOC_STREAMON, &type, "Can't start INPUT"); type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - E_LOG_DEBUG("Starting OUTPUT ..."); - E_XIOCTL(VIDIOC_STREAMON, &type, "Can't start OUTPUT"); + _E_LOG_DEBUG("Starting OUTPUT ..."); + _E_XIOCTL(VIDIOC_STREAMON, &type, "Can't start OUTPUT"); } - RUN(ready) = true; - E_LOG_DEBUG("Encoder state: *** READY ***"); + _RUN(ready) = true; + _E_LOG_DEBUG("Encoder state: *** READY ***"); return; error: _m2m_encoder_cleanup(enc); - E_LOG_ERROR("Encoder destroyed due an error (prepare)"); + _E_LOG_ERROR("Encoder destroyed due an error (prepare)"); } static int _m2m_encoder_init_buffers( - m2m_encoder_s *enc, const char *name, enum v4l2_buf_type type, - m2m_buffer_s **bufs_ptr, unsigned *n_bufs_ptr, bool dma) { + us_m2m_encoder_s *enc, const char *name, enum v4l2_buf_type type, + us_m2m_buffer_s **bufs_ptr, unsigned *n_bufs_ptr, bool dma) { - E_LOG_DEBUG("Initializing %s buffers ...", name); + _E_LOG_DEBUG("Initializing %s buffers ...", name); struct v4l2_requestbuffers req = {0}; req.count = 1; req.type = type; req.memory = (dma ? V4L2_MEMORY_DMABUF : V4L2_MEMORY_MMAP); - E_LOG_DEBUG("Requesting %u %s buffers ...", req.count, name); - E_XIOCTL(VIDIOC_REQBUFS, &req, "Can't request %s buffers", name); + _E_LOG_DEBUG("Requesting %u %s buffers ...", req.count, name); + _E_XIOCTL(VIDIOC_REQBUFS, &req, "Can't request %s buffers", name); if (req.count < 1) { - E_LOG_ERROR("Insufficient %s buffer memory: %u", name, req.count); + _E_LOG_ERROR("Insufficient %s buffer memory: %u", name, req.count); goto error; } - E_LOG_DEBUG("Got %u %s buffers", req.count, name); + _E_LOG_DEBUG("Got %u %s buffers", req.count, name); if (dma) { *n_bufs_ptr = req.count; } else { - A_CALLOC(*bufs_ptr, req.count); + US_CALLOC(*bufs_ptr, req.count); for (*n_bufs_ptr = 0; *n_bufs_ptr < req.count; ++(*n_bufs_ptr)) { struct v4l2_buffer buf = {0}; struct v4l2_plane plane = {0}; @@ -301,25 +301,25 @@ static int _m2m_encoder_init_buffers( buf.length = 1; buf.m.planes = &plane; - E_LOG_DEBUG("Querying %s buffer=%u ...", name, *n_bufs_ptr); - E_XIOCTL(VIDIOC_QUERYBUF, &buf, "Can't query %s buffer=%u", name, *n_bufs_ptr); + _E_LOG_DEBUG("Querying %s buffer=%u ...", name, *n_bufs_ptr); + _E_XIOCTL(VIDIOC_QUERYBUF, &buf, "Can't query %s buffer=%u", name, *n_bufs_ptr); - E_LOG_DEBUG("Mapping %s buffer=%u ...", name, *n_bufs_ptr); + _E_LOG_DEBUG("Mapping %s buffer=%u ...", name, *n_bufs_ptr); if (((*bufs_ptr)[*n_bufs_ptr].data = mmap( NULL, plane.length, PROT_READ | PROT_WRITE, MAP_SHARED, - RUN(fd), + _RUN(fd), plane.m.mem_offset )) == MAP_FAILED) { - E_LOG_PERROR("Can't map %s buffer=%u", name, *n_bufs_ptr); + _E_LOG_PERROR("Can't map %s buffer=%u", name, *n_bufs_ptr); goto error; } (*bufs_ptr)[*n_bufs_ptr].allocated = plane.length; - E_LOG_DEBUG("Queuing %s buffer=%u ...", name, *n_bufs_ptr); - E_XIOCTL(VIDIOC_QBUF, &buf, "Can't queue %s buffer=%u", name, *n_bufs_ptr); + _E_LOG_DEBUG("Queuing %s buffer=%u ...", name, *n_bufs_ptr); + _E_XIOCTL(VIDIOC_QBUF, &buf, "Can't queue %s buffer=%u", name, *n_bufs_ptr); } } @@ -328,13 +328,13 @@ static int _m2m_encoder_init_buffers( return -1; } -static void _m2m_encoder_cleanup(m2m_encoder_s *enc) { - if (RUN(ready)) { -# define STOP_STREAM(_name, _type) { \ - enum v4l2_buf_type _type_var = _type; \ - E_LOG_DEBUG("Stopping %s ...", _name); \ - if (xioctl(RUN(fd), VIDIOC_STREAMOFF, &_type_var) < 0) { \ - E_LOG_PERROR("Can't stop %s", _name); \ +static void _m2m_encoder_cleanup(us_m2m_encoder_s *enc) { + if (_RUN(ready)) { +# define STOP_STREAM(x_name, x_type) { \ + enum v4l2_buf_type m_type_var = x_type; \ + _E_LOG_DEBUG("Stopping %s ...", x_name); \ + if (us_xioctl(_RUN(fd), VIDIOC_STREAMOFF, &m_type_var) < 0) { \ + _E_LOG_PERROR("Can't stop %s", x_name); \ } \ } @@ -344,19 +344,19 @@ static void _m2m_encoder_cleanup(m2m_encoder_s *enc) { # undef STOP_STREAM } -# define DESTROY_BUFFERS(_name, _target) { \ - if (RUN(_target##_bufs)) { \ - for (unsigned index = 0; index < RUN(n_##_target##_bufs); ++index) { \ - if (RUN(_target##_bufs[index].allocated) > 0 && RUN(_target##_bufs[index].data) != MAP_FAILED) { \ - if (munmap(RUN(_target##_bufs[index].data), RUN(_target##_bufs[index].allocated)) < 0) { \ - E_LOG_PERROR("Can't unmap %s buffer=%u", #_name, index); \ +# define DESTROY_BUFFERS(x_name, x_target) { \ + if (_RUN(x_target##_bufs)) { \ + 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) != MAP_FAILED) { \ + if (munmap(_RUN(x_target##_bufs[m_index].data), _RUN(x_target##_bufs[m_index].allocated)) < 0) { \ + _E_LOG_PERROR("Can't unmap %s buffer=%u", #x_name, m_index); \ } \ } \ } \ - free(RUN(_target##_bufs)); \ - RUN(_target##_bufs) = NULL; \ + free(_RUN(x_target##_bufs)); \ + _RUN(x_target##_bufs) = NULL; \ } \ - RUN(n_##_target##_bufs) = 0; \ + _RUN(n_##x_target##_bufs) = 0; \ } DESTROY_BUFFERS("OUTPUT", output); @@ -364,30 +364,30 @@ static void _m2m_encoder_cleanup(m2m_encoder_s *enc) { # undef DESTROY_BUFFERS - if (RUN(fd) >= 0) { - if (close(RUN(fd)) < 0) { - E_LOG_PERROR("Can't close encoder device"); + if (_RUN(fd) >= 0) { + if (close(_RUN(fd)) < 0) { + _E_LOG_PERROR("Can't close encoder device"); } - RUN(fd) = -1; + _RUN(fd) = -1; } - RUN(last_online) = -1; - RUN(ready) = false; + _RUN(last_online) = -1; + _RUN(ready) = false; - E_LOG_DEBUG("Encoder state: ~~~ NOT READY ~~~"); + _E_LOG_DEBUG("Encoder state: ~~~ NOT READY ~~~"); } -static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key) { - assert(RUN(ready)); +static int _m2m_encoder_compress_raw(us_m2m_encoder_s *enc, const us_frame_s *src, us_frame_s *dest, bool force_key) { + assert(_RUN(ready)); - E_LOG_DEBUG("Compressing new frame; force_key=%d ...", force_key); + _E_LOG_DEBUG("Compressing new frame; force_key=%d ...", force_key); if (force_key) { struct v4l2_control ctl = {0}; ctl.id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME; ctl.value = 1; - E_LOG_DEBUG("Forcing keyframe ...") - E_XIOCTL(VIDIOC_S_CTRL, &ctl, "Can't force keyframe"); + _E_LOG_DEBUG("Forcing keyframe ...") + _E_XIOCTL(VIDIOC_S_CTRL, &ctl, "Can't force keyframe"); } struct v4l2_buffer input_buf = {0}; @@ -396,25 +396,25 @@ static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, fra input_buf.length = 1; input_buf.m.planes = &input_plane; - if (RUN(dma)) { + if (_RUN(dma)) { input_buf.index = 0; input_buf.memory = V4L2_MEMORY_DMABUF; input_buf.field = V4L2_FIELD_NONE; input_plane.m.fd = src->dma_fd; - E_LOG_DEBUG("Using INPUT-DMA buffer=%u", input_buf.index); + _E_LOG_DEBUG("Using INPUT-DMA buffer=%u", input_buf.index); } else { input_buf.memory = V4L2_MEMORY_MMAP; - E_LOG_DEBUG("Grabbing INPUT buffer ..."); - E_XIOCTL(VIDIOC_DQBUF, &input_buf, "Can't grab INPUT buffer"); - if (input_buf.index >= RUN(n_input_bufs)) { - E_LOG_ERROR("V4L2 error: grabbed invalid INPUT: buffer=%u, n_bufs=%u", - input_buf.index, RUN(n_input_bufs)); + _E_LOG_DEBUG("Grabbing INPUT buffer ..."); + _E_XIOCTL(VIDIOC_DQBUF, &input_buf, "Can't grab INPUT buffer"); + if (input_buf.index >= _RUN(n_input_bufs)) { + _E_LOG_ERROR("V4L2 error: grabbed invalid INPUT: buffer=%u, n_bufs=%u", + input_buf.index, _RUN(n_input_bufs)); goto error; } - E_LOG_DEBUG("Grabbed INPUT buffer=%u", input_buf.index); + _E_LOG_DEBUG("Grabbed INPUT buffer=%u", input_buf.index); } - uint64_t now = get_now_monotonic_u64(); + uint64_t now = us_get_now_monotonic_u64(); struct timeval ts = { .tv_sec = now / 1000000, .tv_usec = now % 1000000, @@ -424,31 +424,31 @@ static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, fra input_buf.timestamp.tv_usec = ts.tv_usec; input_plane.bytesused = src->used; input_plane.length = src->used; - if (!RUN(dma)) { - memcpy(RUN(input_bufs[input_buf.index].data), src->data, src->used); + if (!_RUN(dma)) { + memcpy(_RUN(input_bufs[input_buf.index].data), src->data, src->used); } - const char *input_name = (RUN(dma) ? "INPUT-DMA" : "INPUT"); + const char *input_name = (_RUN(dma) ? "INPUT-DMA" : "INPUT"); - E_LOG_DEBUG("Sending%s %s buffer ...", (!RUN(dma) ? " (releasing)" : ""), input_name); - E_XIOCTL(VIDIOC_QBUF, &input_buf, "Can't send %s buffer", input_name); + _E_LOG_DEBUG("Sending%s %s buffer ...", (!_RUN(dma) ? " (releasing)" : ""), input_name); + _E_XIOCTL(VIDIOC_QBUF, &input_buf, "Can't send %s buffer", input_name); // Для не-DMA отправка буфера по факту являтся освобождением этого буфера - bool input_released = !RUN(dma); + bool input_released = !_RUN(dma); while (true) { - struct pollfd enc_poll = {RUN(fd), POLLIN, 0}; + struct pollfd enc_poll = {_RUN(fd), POLLIN, 0}; - E_LOG_DEBUG("Polling encoder ..."); + _E_LOG_DEBUG("Polling encoder ..."); if (poll(&enc_poll, 1, 1000) < 0 && errno != EINTR) { - E_LOG_PERROR("Can't poll encoder"); + _E_LOG_PERROR("Can't poll encoder"); goto error; } if (enc_poll.revents & POLLIN) { if (!input_released) { - E_LOG_DEBUG("Releasing %s buffer=%u ...", input_name, input_buf.index); - E_XIOCTL(VIDIOC_DQBUF, &input_buf, "Can't release %s buffer=%u", + _E_LOG_DEBUG("Releasing %s buffer=%u ...", input_name, input_buf.index); + _E_XIOCTL(VIDIOC_DQBUF, &input_buf, "Can't release %s buffer=%u", input_name, input_buf.index); input_released = true; } @@ -459,23 +459,23 @@ static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, fra output_buf.memory = V4L2_MEMORY_MMAP; output_buf.length = 1; output_buf.m.planes = &output_plane; - E_LOG_DEBUG("Fetching OUTPUT buffer ..."); - E_XIOCTL(VIDIOC_DQBUF, &output_buf, "Can't fetch OUTPUT buffer"); + _E_LOG_DEBUG("Fetching OUTPUT buffer ..."); + _E_XIOCTL(VIDIOC_DQBUF, &output_buf, "Can't fetch OUTPUT buffer"); bool done = false; if (ts.tv_sec != output_buf.timestamp.tv_sec || ts.tv_usec != output_buf.timestamp.tv_usec) { // Енкодер первый раз может выдать буфер с мусором и нулевым таймстампом, // так что нужно убедиться, что мы читаем выходной буфер, соответствующий // входному (с тем же таймстампом). - E_LOG_DEBUG("Need to retry OUTPUT buffer due timestamp mismatch"); + _E_LOG_DEBUG("Need to retry OUTPUT buffer due timestamp mismatch"); } else { - frame_set_data(dest, RUN(output_bufs[output_buf.index].data), output_plane.bytesused); + us_frame_set_data(dest, _RUN(output_bufs[output_buf.index].data), output_plane.bytesused); dest->key = output_buf.flags & V4L2_BUF_FLAG_KEYFRAME; done = true; } - E_LOG_DEBUG("Releasing OUTPUT buffer=%u ...", output_buf.index); - E_XIOCTL(VIDIOC_QBUF, &output_buf, "Can't release OUTPUT buffer=%u", output_buf.index); + _E_LOG_DEBUG("Releasing OUTPUT buffer=%u ...", output_buf.index); + _E_XIOCTL(VIDIOC_QBUF, &output_buf, "Can't release OUTPUT buffer=%u", output_buf.index); if (done) { break; @@ -488,12 +488,4 @@ static int _m2m_encoder_compress_raw(m2m_encoder_s *enc, const frame_s *src, fra return -1; } -#undef E_XIOCTL - -#undef RUN - -#undef E_LOG_DEBUG -#undef E_LOG_VERBOSE -#undef E_LOG_INFO -#undef E_LOG_PERROR -#undef E_LOG_ERROR +#undef _E_XIOCTL diff --git a/src/ustreamer/m2m.h b/src/ustreamer/m2m.h index 82ebc9b..b1e6eda 100644 --- a/src/ustreamer/m2m.h +++ b/src/ustreamer/m2m.h @@ -45,24 +45,24 @@ typedef struct { uint8_t *data; size_t allocated; -} m2m_buffer_s; +} us_m2m_buffer_s; typedef struct { int fd; - m2m_buffer_s *input_bufs; + us_m2m_buffer_s *input_bufs; unsigned n_input_bufs; - m2m_buffer_s *output_bufs; + us_m2m_buffer_s *output_bufs; unsigned n_output_bufs; - unsigned width; - unsigned height; - unsigned input_format; - unsigned stride; - bool dma; - bool ready; + unsigned width; + unsigned height; + unsigned input_format; + unsigned stride; + bool dma; + bool ready; - int last_online; -} m2m_encoder_runtime_s; + int last_online; +} us_m2m_encoder_runtime_s; typedef struct { char *name; @@ -74,13 +74,13 @@ typedef struct { unsigned quality; bool allow_dma; - m2m_encoder_runtime_s *run; -} m2m_encoder_s; + us_m2m_encoder_runtime_s *run; +} us_m2m_encoder_s; -m2m_encoder_s *m2m_h264_encoder_init(const char *name, const char *path, unsigned bitrate, unsigned gop); -m2m_encoder_s *m2m_mjpeg_encoder_init(const char *name, const char *path, unsigned quality); -m2m_encoder_s *m2m_jpeg_encoder_init(const char *name, const char *path, unsigned quality); -void m2m_encoder_destroy(m2m_encoder_s *enc); +us_m2m_encoder_s *us_m2m_h264_encoder_init(const char *name, const char *path, unsigned bitrate, unsigned gop); +us_m2m_encoder_s *us_m2m_mjpeg_encoder_init(const char *name, const char *path, unsigned quality); +us_m2m_encoder_s *us_m2m_jpeg_encoder_init(const char *name, const char *path, unsigned quality); +void us_m2m_encoder_destroy(us_m2m_encoder_s *enc); -int m2m_encoder_compress(m2m_encoder_s *enc, const frame_s *src, frame_s *dest, bool force_key); +int us_m2m_encoder_compress(us_m2m_encoder_s *enc, const us_frame_s *src, us_frame_s *dest, bool force_key); diff --git a/src/ustreamer/main.c b/src/ustreamer/main.c index 1039194..5c20b7d 100644 --- a/src/ustreamer/main.c +++ b/src/ustreamer/main.c @@ -41,8 +41,8 @@ typedef struct { - stream_s *stream; - server_s *server; + us_stream_s *stream; + us_server_s *server; } _main_context_s; static _main_context_s *_ctx; @@ -56,27 +56,27 @@ static void _block_thread_signals(void) { } static void *_stream_loop_thread(UNUSED void *arg) { - A_THREAD_RENAME("stream"); + US_THREAD_RENAME("stream"); _block_thread_signals(); - stream_loop(_ctx->stream); + us_stream_loop(_ctx->stream); return NULL; } static void *_server_loop_thread(UNUSED void *arg) { - A_THREAD_RENAME("http"); + US_THREAD_RENAME("http"); _block_thread_signals(); - server_loop(_ctx->server); + us_server_loop(_ctx->server); return NULL; } static void _signal_handler(int signum) { switch (signum) { - case SIGTERM: LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break; - case SIGINT: LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break; - default: LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break; + case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break; + case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break; + default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break; } - stream_loop_break(_ctx->stream); - server_loop_break(_ctx->server); + us_stream_loop_break(_ctx->stream); + us_server_loop_break(_ctx->server); } static void _install_signal_handlers(void) { @@ -87,13 +87,13 @@ static void _install_signal_handlers(void) { assert(!sigaddset(&sig_act.sa_mask, SIGINT)); assert(!sigaddset(&sig_act.sa_mask, SIGTERM)); - LOG_DEBUG("Installing SIGINT handler ..."); + US_LOG_DEBUG("Installing SIGINT handler ..."); assert(!sigaction(SIGINT, &sig_act, NULL)); - LOG_DEBUG("Installing SIGTERM handler ..."); + US_LOG_DEBUG("Installing SIGTERM handler ..."); assert(!sigaction(SIGTERM, &sig_act, NULL)); - LOG_DEBUG("Ignoring SIGPIPE ..."); + US_LOG_DEBUG("Ignoring SIGPIPE ..."); assert(signal(SIGPIPE, SIG_IGN) != SIG_ERR); } @@ -101,18 +101,18 @@ int main(int argc, char *argv[]) { assert(argc >= 0); int exit_code = 0; - LOGGING_INIT; - A_THREAD_RENAME("main"); + US_LOGGING_INIT; + US_THREAD_RENAME("main"); - options_s *options = options_init(argc, argv); - device_s *dev = device_init(); - encoder_s *enc = encoder_init(); - stream_s *stream = stream_init(dev, enc); - server_s *server = server_init(stream); + us_options_s *options = us_options_init(argc, argv); + us_device_s *dev = us_device_init(); + us_encoder_s *enc = us_encoder_init(); + us_stream_s *stream = us_stream_init(dev, enc); + us_server_s *server = us_server_init(stream); if ((exit_code = options_parse(options, dev, enc, stream, server)) == 0) { # ifdef WITH_GPIO - gpio_init(); + us_gpio_init(); # endif _install_signal_handlers(); @@ -122,34 +122,34 @@ int main(int argc, char *argv[]) { ctx.server = server; _ctx = &ctx; - if ((exit_code = server_listen(server)) == 0) { + if ((exit_code = us_server_listen(server)) == 0) { # ifdef WITH_GPIO - gpio_set_prog_running(true); + us_gpio_set_prog_running(true); # endif pthread_t stream_loop_tid; pthread_t server_loop_tid; - A_THREAD_CREATE(&stream_loop_tid, _stream_loop_thread, NULL); - A_THREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL); - A_THREAD_JOIN(server_loop_tid); - A_THREAD_JOIN(stream_loop_tid); + US_THREAD_CREATE(&stream_loop_tid, _stream_loop_thread, NULL); + US_THREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL); + US_THREAD_JOIN(server_loop_tid); + US_THREAD_JOIN(stream_loop_tid); } # ifdef WITH_GPIO - gpio_set_prog_running(false); - gpio_destroy(); + us_gpio_set_prog_running(false); + us_gpio_destroy(); # endif } - server_destroy(server); - stream_destroy(stream); - encoder_destroy(enc); - device_destroy(dev); - options_destroy(options); + us_server_destroy(server); + us_stream_destroy(stream); + us_encoder_destroy(enc); + us_device_destroy(dev); + us_options_destroy(options); if (exit_code == 0) { - LOG_INFO("Bye-bye"); + US_LOG_INFO("Bye-bye"); } - LOGGING_DESTROY; + US_LOGGING_DESTROY; return (exit_code < 0 ? 1 : 0); } diff --git a/src/ustreamer/options.c b/src/ustreamer/options.c index 4109b56..a8f3409 100644 --- a/src/ustreamer/options.c +++ b/src/ustreamer/options.c @@ -23,7 +23,7 @@ #include "options.h" -enum _OPT_VALUES { +enum _US_OPT_VALUES { _O_DEVICE = 'd', _O_INPUT = 'i', _O_RESOLUTION = 'r', @@ -85,12 +85,12 @@ enum _OPT_VALUES { _O_TCP_NODELAY, _O_SERVER_TIMEOUT, -# define ADD_SINK(_prefix) \ - _O_##_prefix, \ - _O_##_prefix##_MODE, \ - _O_##_prefix##_RM, \ - _O_##_prefix##_CLIENT_TTL, \ - _O_##_prefix##_TIMEOUT, +# define ADD_SINK(x_prefix) \ + _O_##x_prefix, \ + _O_##x_prefix##_MODE, \ + _O_##x_prefix##_RM, \ + _O_##x_prefix##_CLIENT_TTL, \ + _O_##x_prefix##_TIMEOUT, ADD_SINK(SINK) ADD_SINK(RAW_SINK) ADD_SINK(H264_SINK) @@ -181,12 +181,12 @@ static const struct option _LONG_OPTS[] = { {"tcp-nodelay", no_argument, NULL, _O_TCP_NODELAY}, {"server-timeout", required_argument, NULL, _O_SERVER_TIMEOUT}, -# define ADD_SINK(_opt, _prefix) \ - {_opt "sink", required_argument, NULL, _O_##_prefix}, \ - {_opt "sink-mode", required_argument, NULL, _O_##_prefix##_MODE}, \ - {_opt "sink-rm", no_argument, NULL, _O_##_prefix##_RM}, \ - {_opt "sink-client-ttl", required_argument, NULL, _O_##_prefix##_CLIENT_TTL}, \ - {_opt "sink-timeout", required_argument, NULL, _O_##_prefix##_TIMEOUT}, +# define ADD_SINK(x_opt, x_prefix) \ + {x_opt "sink", required_argument, NULL, _O_##x_prefix}, \ + {x_opt "sink-mode", required_argument, NULL, _O_##x_prefix##_MODE}, \ + {x_opt "sink-rm", no_argument, NULL, _O_##x_prefix##_RM}, \ + {x_opt "sink-client-ttl", required_argument, NULL, _O_##x_prefix##_CLIENT_TTL}, \ + {x_opt "sink-timeout", required_argument, NULL, _O_##x_prefix##_TIMEOUT}, ADD_SINK("", SINK) ADD_SINK("raw-", RAW_SINK) ADD_SINK("h264-", H264_SINK) @@ -230,36 +230,28 @@ static const struct option _LONG_OPTS[] = { static int _parse_resolution(const char *str, unsigned *width, unsigned *height, bool limited); static void _features(void); -static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server); +static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *stream, us_server_s *server); -options_s *options_init(unsigned argc, char *argv[]) { - options_s *options; - A_CALLOC(options, 1); +us_options_s *us_options_init(unsigned argc, char *argv[]) { + us_options_s *options; + US_CALLOC(options, 1); options->argc = argc; options->argv = argv; - A_CALLOC(options->argv_copy, argc); + US_CALLOC(options->argv_copy, argc); for (unsigned index = 0; index < argc; ++index) { assert(options->argv_copy[index] = strdup(argv[index])); } return options; } -void options_destroy(options_s *options) { -# define ADD_SINK(_prefix) { \ - if (options->_prefix) { \ - memsink_destroy(options->_prefix); \ - } \ - } - ADD_SINK(sink); - ADD_SINK(raw_sink); - ADD_SINK(h264_sink); -# undef ADD_SINK +void us_options_destroy(us_options_s *options) { + US_DELETE(options->sink, us_memsink_destroy); + US_DELETE(options->raw_sink, us_memsink_destroy); + US_DELETE(options->h264_sink, us_memsink_destroy); - if (options->blank) { - frame_destroy(options->blank); - } + US_DELETE(options->blank, us_frame_destroy); for (unsigned index = 0; index < options->argc; ++index) { free(options->argv_copy[index]); @@ -270,32 +262,32 @@ void options_destroy(options_s *options) { } -int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server) { -# define OPT_SET(_dest, _value) { \ - _dest = _value; \ +int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us_stream_s *stream, us_server_s *server) { +# define OPT_SET(x_dest, x_value) { \ + x_dest = x_value; \ break; \ } -# define OPT_NUMBER(_name, _dest, _min, _max, _base) { \ - errno = 0; char *_end = NULL; long long _tmp = strtoll(optarg, &_end, _base); \ - if (errno || *_end || _tmp < _min || _tmp > _max) { \ - printf("Invalid value for '%s=%s': min=%lld, max=%lld\n", _name, optarg, (long long)_min, (long long)_max); \ +# 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); \ + 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; \ } \ - _dest = _tmp; \ + x_dest = m_tmp; \ break; \ } -# define OPT_RESOLUTION(_name, _dest_width, _dest_height, _limited) { \ - switch (_parse_resolution(optarg, &_dest_width, &_dest_height, _limited)) { \ +# define OPT_RESOLUTION(x_name, x_dest_width, x_dest_height, x_limited) { \ + switch (_parse_resolution(optarg, &x_dest_width, &x_dest_height, x_limited)) { \ case -1: \ - printf("Invalid resolution format for '%s=%s'\n", _name, optarg); \ + printf("Invalid resolution format for '%s=%s'\n", x_name, optarg); \ return -1; \ case -2: \ - printf("Invalid width of '%s=%s': min=%u, max=%u\n", _name, optarg, VIDEO_MIN_WIDTH, VIDEO_MAX_WIDTH); \ + printf("Invalid width of '%s=%s': min=%u, max=%u\n", x_name, optarg, US_VIDEO_MIN_WIDTH, US_VIDEO_MAX_WIDTH); \ return -1; \ case -3: \ - printf("Invalid height of '%s=%s': min=%u, max=%u\n", _name, optarg, VIDEO_MIN_HEIGHT, VIDEO_MAX_HEIGHT); \ + printf("Invalid height of '%s=%s': min=%u, max=%u\n", x_name, optarg, US_VIDEO_MIN_HEIGHT, US_VIDEO_MAX_HEIGHT); \ return -1; \ case 0: break; \ default: assert(0 && "Unknown error"); \ @@ -303,48 +295,48 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s break; \ } -# define OPT_PARSE(_name, _dest, _func, _invalid, _available) { \ - if ((_dest = _func(optarg)) == _invalid) { \ - printf("Unknown " _name ": %s; available: %s\n", optarg, _available); \ +# define OPT_PARSE(x_name, x_dest, x_func, x_invalid, x_available) { \ + if ((x_dest = x_func(optarg)) == x_invalid) { \ + printf("Unknown " x_name ": %s; available: %s\n", optarg, x_available); \ return -1; \ } \ break; \ } -# define OPT_CTL_DEFAULT_NOBREAK(_dest) { \ - dev->ctl._dest.mode = CTL_MODE_DEFAULT; \ +# define OPT_CTL_DEFAULT_NOBREAK(x_dest) { \ + dev->ctl.x_dest.mode = CTL_MODE_DEFAULT; \ } -# define OPT_CTL_MANUAL(_dest) { \ +# define OPT_CTL_MANUAL(x_dest) { \ if (!strcasecmp(optarg, "default")) { \ - OPT_CTL_DEFAULT_NOBREAK(_dest); \ + OPT_CTL_DEFAULT_NOBREAK(x_dest); \ } else { \ - dev->ctl._dest.mode = CTL_MODE_VALUE; \ - OPT_NUMBER("--"#_dest, dev->ctl._dest.value, INT_MIN, INT_MAX, 0); \ + dev->ctl.x_dest.mode = CTL_MODE_VALUE; \ + OPT_NUMBER("--"#x_dest, dev->ctl.x_dest.value, INT_MIN, INT_MAX, 0); \ } \ break; \ } -# define OPT_CTL_AUTO(_dest) { \ +# define OPT_CTL_AUTO(x_dest) { \ if (!strcasecmp(optarg, "default")) { \ - OPT_CTL_DEFAULT_NOBREAK(_dest); \ + OPT_CTL_DEFAULT_NOBREAK(x_dest); \ } else if (!strcasecmp(optarg, "auto")) { \ - dev->ctl._dest.mode = CTL_MODE_AUTO; \ + dev->ctl.x_dest.mode = CTL_MODE_AUTO; \ } else { \ - dev->ctl._dest.mode = CTL_MODE_VALUE; \ - OPT_NUMBER("--"#_dest, dev->ctl._dest.value, INT_MIN, INT_MAX, 0); \ + dev->ctl.x_dest.mode = CTL_MODE_VALUE; \ + OPT_NUMBER("--"#x_dest, dev->ctl.x_dest.value, INT_MIN, INT_MAX, 0); \ } \ break; \ } char *blank_path = NULL; -# define ADD_SINK(_prefix) \ - char *_prefix##_name = NULL; \ - mode_t _prefix##_mode = 0660; \ - bool _prefix##_rm = false; \ - unsigned _prefix##_client_ttl = 10; \ - unsigned _prefix##_timeout = 1; +# define ADD_SINK(x_prefix) \ + char *x_prefix##_name = NULL; \ + mode_t x_prefix##_mode = 0660; \ + bool x_prefix##_rm = false; \ + unsigned x_prefix##_client_ttl = 10; \ + unsigned x_prefix##_timeout = 1; ADD_SINK(sink); ADD_SINK(raw_sink); ADD_SINK(h264_sink); @@ -355,27 +347,27 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s # endif char short_opts[128]; - build_short_options(_LONG_OPTS, short_opts, 128); + us_build_short_options(_LONG_OPTS, short_opts, 128); for (int ch; (ch = getopt_long(options->argc, options->argv_copy, short_opts, _LONG_OPTS, NULL)) >= 0;) { switch (ch) { - case _O_DEVICE: OPT_SET(dev->path, optarg); - case _O_INPUT: OPT_NUMBER("--input", dev->input, 0, 128, 0); - case _O_RESOLUTION: OPT_RESOLUTION("--resolution", dev->width, dev->height, true); + case _O_DEVICE: OPT_SET(dev->path, optarg); + case _O_INPUT: OPT_NUMBER("--input", dev->input, 0, 128, 0); + case _O_RESOLUTION: OPT_RESOLUTION("--resolution", dev->width, dev->height, true); # pragma GCC diagnostic ignored "-Wsign-compare" # pragma GCC diagnostic push - case _O_FORMAT: OPT_PARSE("pixel format", dev->format, device_parse_format, FORMAT_UNKNOWN, FORMATS_STR); + case _O_FORMAT: OPT_PARSE("pixel format", dev->format, us_device_parse_format, US_FORMAT_UNKNOWN, US_FORMATS_STR); # pragma GCC diagnostic pop - case _O_TV_STANDARD: OPT_PARSE("TV standard", dev->standard, device_parse_standard, STANDARD_UNKNOWN, STANDARDS_STR); - case _O_IO_METHOD: OPT_PARSE("IO method", dev->io_method, device_parse_io_method, IO_METHOD_UNKNOWN, IO_METHODS_STR); - case _O_DESIRED_FPS: OPT_NUMBER("--desired-fps", dev->desired_fps, 0, VIDEO_MAX_FPS, 0); - case _O_MIN_FRAME_SIZE: OPT_NUMBER("--min-frame-size", dev->min_frame_size, 1, 8192, 0); - case _O_PERSISTENT: OPT_SET(dev->persistent, true); - case _O_DV_TIMINGS: OPT_SET(dev->dv_timings, true); - case _O_BUFFERS: OPT_NUMBER("--buffers", dev->n_bufs, 1, 32, 0); - case _O_WORKERS: OPT_NUMBER("--workers", enc->n_workers, 1, 32, 0); - case _O_QUALITY: OPT_NUMBER("--quality", dev->jpeg_quality, 1, 100, 0); - case _O_ENCODER: OPT_PARSE("encoder type", enc->type, encoder_parse_type, ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR); + case _O_TV_STANDARD: OPT_PARSE("TV standard", dev->standard, us_device_parse_standard, US_STANDARD_UNKNOWN, US_STANDARDS_STR); + case _O_IO_METHOD: OPT_PARSE("IO method", dev->io_method, us_device_parse_io_method, US_IO_METHOD_UNKNOWN, US_IO_METHODS_STR); + case _O_DESIRED_FPS: OPT_NUMBER("--desired-fps", dev->desired_fps, 0, US_VIDEO_MAX_FPS, 0); + case _O_MIN_FRAME_SIZE: OPT_NUMBER("--min-frame-size", dev->min_frame_size, 1, 8192, 0); + case _O_PERSISTENT: OPT_SET(dev->persistent, true); + case _O_DV_TIMINGS: OPT_SET(dev->dv_timings, true); + case _O_BUFFERS: OPT_NUMBER("--buffers", dev->n_bufs, 1, 32, 0); + case _O_WORKERS: OPT_NUMBER("--workers", enc->n_workers, 1, 32, 0); + case _O_QUALITY: OPT_NUMBER("--quality", dev->jpeg_quality, 1, 100, 0); + case _O_ENCODER: OPT_PARSE("encoder type", enc->type, us_encoder_parse_type, US_ENCODER_TYPE_UNKNOWN, ENCODER_TYPES_STR); case _O_GLITCHED_RESOLUTIONS: break; // Deprecated case _O_BLANK: OPT_SET(blank_path, optarg); case _O_LAST_AS_BLANK: OPT_NUMBER("--last-as-blank", stream->last_as_blank, 0, 86400, 0); @@ -409,7 +401,7 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s case _O_WHITE_BALANCE: OPT_CTL_AUTO(white_balance); case _O_GAIN: OPT_CTL_AUTO(gain); case _O_COLOR_EFFECT: OPT_CTL_MANUAL(color_effect); - case _O_ROTATE: OPT_CTL_MANUAL(rotate); + case _O_ROTATE: OPT_CTL_MANUAL(rotate); case _O_FLIP_VERTICAL: OPT_CTL_MANUAL(flip_vertical); case _O_FLIP_HORIZONTAL: OPT_CTL_MANUAL(flip_horizontal); @@ -424,24 +416,24 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s case _O_USER: OPT_SET(server->user, optarg); case _O_PASSWD: OPT_SET(server->passwd, optarg); case _O_STATIC: OPT_SET(server->static_path, optarg); - case _O_DROP_SAME_FRAMES: OPT_NUMBER("--drop-same-frames", server->drop_same_frames, 0, VIDEO_MAX_FPS, 0); + case _O_DROP_SAME_FRAMES: OPT_NUMBER("--drop-same-frames", server->drop_same_frames, 0, US_VIDEO_MAX_FPS, 0); case _O_FAKE_RESOLUTION: OPT_RESOLUTION("--fake-resolution", server->fake_width, server->fake_height, false); case _O_ALLOW_ORIGIN: OPT_SET(server->allow_origin, optarg); case _O_TCP_NODELAY: OPT_SET(server->tcp_nodelay, true); case _O_SERVER_TIMEOUT: OPT_NUMBER("--server-timeout", server->timeout, 1, 60, 0); -# define ADD_SINK(_opt, _lp, _up) \ - case _O_##_up: OPT_SET(_lp##_name, optarg); \ - case _O_##_up##_MODE: OPT_NUMBER("--" #_opt "sink-mode", _lp##_mode, INT_MIN, INT_MAX, 8); \ - case _O_##_up##_RM: OPT_SET(_lp##_rm, true); \ - case _O_##_up##_CLIENT_TTL: OPT_NUMBER("--" #_opt "sink-client-ttl", _lp##_client_ttl, 1, 60, 0); \ - case _O_##_up##_TIMEOUT: OPT_NUMBER("--" #_opt "sink-timeout", _lp##_timeout, 1, 60, 0); +# define ADD_SINK(x_opt, x_lp, x_up) \ + case _O_##x_up: OPT_SET(x_lp##_name, optarg); \ + case _O_##x_up##_MODE: OPT_NUMBER("--" #x_opt "sink-mode", x_lp##_mode, INT_MIN, INT_MAX, 8); \ + case _O_##x_up##_RM: OPT_SET(x_lp##_rm, true); \ + case _O_##x_up##_CLIENT_TTL: OPT_NUMBER("--" #x_opt "sink-client-ttl", x_lp##_client_ttl, 1, 60, 0); \ + case _O_##x_up##_TIMEOUT: OPT_NUMBER("--" #x_opt "sink-timeout", x_lp##_timeout, 1, 60, 0); ADD_SINK("", sink, SINK) ADD_SINK("raw-", raw_sink, RAW_SINK) ADD_SINK("h264-", h264_sink, H264_SINK) - case _O_H264_BITRATE: OPT_NUMBER("--h264-bitrate", stream->h264_bitrate, 25, 20000, 0); - case _O_H264_GOP: OPT_NUMBER("--h264-gop", stream->h264_gop, 0, 60, 0); - case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg); + case _O_H264_BITRATE: OPT_NUMBER("--h264-bitrate", stream->h264_bitrate, 25, 20000, 0); + case _O_H264_GOP: OPT_NUMBER("--h264-gop", stream->h264_gop, 0, 60, 0); + case _O_H264_M2M_DEVICE: OPT_SET(stream->h264_m2m_path, optarg); # undef ADD_SINK # ifdef WITH_GPIO @@ -454,7 +446,7 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s # ifdef HAS_PDEATHSIG case _O_EXIT_ON_PARENT_DEATH: - if (process_track_parent_death() < 0) { + if (us_process_track_parent_death() < 0) { return -1; }; break; @@ -465,15 +457,15 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s # endif case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true); - case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, 0); - case _O_PERF: OPT_SET(us_log_level, LOG_LEVEL_PERF); - case _O_VERBOSE: OPT_SET(us_log_level, LOG_LEVEL_VERBOSE); - case _O_DEBUG: OPT_SET(us_log_level, LOG_LEVEL_DEBUG); + case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0); + case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF); + case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE); + case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG); case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true); case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false); case _O_HELP: _help(stdout, dev, enc, stream, server); return 1; - case _O_VERSION: puts(VERSION); return 1; + case _O_VERSION: puts(US_VERSION); return 1; case _O_FEATURES: _features(); return 1; case 0: break; @@ -481,22 +473,22 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s } } - options->blank = blank_frame_init(blank_path); + options->blank = us_blank_frame_init(blank_path); stream->blank = options->blank; -# define ADD_SINK(_label, _prefix) { \ - if (_prefix##_name && _prefix##_name[0] != '\0') { \ - options->_prefix = memsink_init( \ - _label, \ - _prefix##_name, \ +# define ADD_SINK(x_label, x_prefix) { \ + if (x_prefix##_name && x_prefix##_name[0] != '\0') { \ + options->x_prefix = us_memsink_init( \ + x_label, \ + x_prefix##_name, \ true, \ - _prefix##_mode, \ - _prefix##_rm, \ - _prefix##_client_ttl, \ - _prefix##_timeout \ + x_prefix##_mode, \ + x_prefix##_rm, \ + x_prefix##_client_ttl, \ + x_prefix##_timeout \ ); \ } \ - stream->_prefix = options->_prefix; \ + stream->x_prefix = options->x_prefix; \ } ADD_SINK("JPEG", sink); ADD_SINK("RAW", raw_sink); @@ -505,7 +497,7 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s # ifdef WITH_SETPROCTITLE if (process_name_prefix != NULL) { - process_set_name_prefix(options->argc, options->argv, process_name_prefix); + us_process_set_name_prefix(options->argc, options->argv, process_name_prefix); } # endif @@ -526,10 +518,10 @@ static int _parse_resolution(const char *str, unsigned *width, unsigned *height, return -1; } if (limited) { - if (tmp_width < VIDEO_MIN_WIDTH || tmp_width > VIDEO_MAX_WIDTH) { + if (tmp_width < US_VIDEO_MIN_WIDTH || tmp_width > US_VIDEO_MAX_WIDTH) { return -2; } - if (tmp_height < VIDEO_MIN_HEIGHT || tmp_height > VIDEO_MAX_HEIGHT) { + if (tmp_height < US_VIDEO_MIN_HEIGHT || tmp_height > US_VIDEO_MAX_HEIGHT) { return -3; } } @@ -570,11 +562,11 @@ static void _features(void) { # endif } -static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server) { -# define SAY(_msg, ...) fprintf(fp, _msg "\n", ##__VA_ARGS__) +static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *stream, us_server_s *server) { +# define SAY(x_msg, ...) fprintf(fp, x_msg "\n", ##__VA_ARGS__) SAY("\nuStreamer - Lightweight and fast MJPEG-HTTP streamer"); SAY("═══════════════════════════════════════════════════"); - SAY("Version: %s; license: GPLv3", VERSION); + SAY("Version: %s; license: GPLv3", US_VERSION); SAY("Copyright (C) 2018-2022 Maxim Devaev \n"); SAY("Capturing options:"); SAY("══════════════════"); @@ -582,12 +574,12 @@ static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, ser SAY(" -i|--input ────────────────────── Input channel. Default: %u.\n", dev->input); SAY(" -r|--resolution ─────────────── Initial image resolution. Default: %ux%u.\n", dev->width, dev->height); SAY(" -m|--format ─────────────────── Image format."); - SAY(" Available: %s; default: YUYV.\n", FORMATS_STR); + SAY(" Available: %s; default: YUYV.\n", US_FORMATS_STR); SAY(" -a|--tv-standard ────────────── Force TV standard."); - SAY(" Available: %s; default: disabled.\n", STANDARDS_STR); + SAY(" Available: %s; default: disabled.\n", US_STANDARDS_STR); SAY(" -I|--io-method ───────────── Set V4L2 IO method (see kernel documentation)."); SAY(" Changing of this parameter may increase the performance. Or not."); - SAY(" Available: %s; default: MMAP.\n", IO_METHODS_STR); + SAY(" Available: %s; default: MMAP.\n", US_IO_METHODS_STR); SAY(" -f|--desired-fps ──────────────── Desired FPS. Default: maximum possible.\n"); SAY(" -z|--min-frame-size ───────────── Drop frames smaller then this limit. Useful if the device"); SAY(" produces small-sized garbage frames. Default: %zu bytes.\n", dev->min_frame_size); @@ -666,14 +658,14 @@ static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, ser SAY(" Default: disabled.\n"); SAY(" --allow-origin ─────── Set Access-Control-Allow-Origin header. Default: disabled.\n"); SAY(" --server-timeout ───── Timeout for client connections. Default: %u.\n", server->timeout); -# define ADD_SINK(_name, _opt) \ - SAY(_name " sink options:"); \ +# define ADD_SINK(x_name, x_opt) \ + SAY(x_name " sink options:"); \ SAY("══════════════════"); \ - SAY(" --" _opt "sink ──────────── Use the shared memory to sink " _name " frames. Default: disabled.\n"); \ - SAY(" --" _opt "sink-mode ─────── Set " _name " sink permissions (like 777). Default: 660.\n"); \ - SAY(" --" _opt "sink-rm ──────────────── Remove shared memory on stop. Default: disabled.\n"); \ - SAY(" --" _opt "sink-client-ttl ── Client TTL. Default: 10.\n"); \ - SAY(" --" _opt "sink-timeout ───── Timeout for lock. Default: 1.\n"); + SAY(" --" x_opt "sink ──────────── Use the shared memory to sink " x_name " frames. Default: disabled.\n"); \ + SAY(" --" x_opt "sink-mode ─────── Set " x_name " sink permissions (like 777). Default: 660.\n"); \ + SAY(" --" x_opt "sink-rm ──────────────── Remove shared memory on stop. Default: disabled.\n"); \ + SAY(" --" x_opt "sink-client-ttl ── Client TTL. Default: 10.\n"); \ + SAY(" --" x_opt "sink-timeout ───── Timeout for lock. Default: 1.\n"); ADD_SINK("JPEG", "") ADD_SINK("RAW", "raw-") ADD_SINK("H264", "h264-") diff --git a/src/ustreamer/options.h b/src/ustreamer/options.h index cd8f74d..8cc98ad 100644 --- a/src/ustreamer/options.h +++ b/src/ustreamer/options.h @@ -50,17 +50,17 @@ typedef struct { - unsigned argc; - char **argv; - char **argv_copy; - frame_s *blank; - memsink_s *sink; - memsink_s *raw_sink; - memsink_s *h264_sink; -} options_s; + unsigned argc; + char **argv; + char **argv_copy; + us_frame_s *blank; + us_memsink_s *sink; + us_memsink_s *raw_sink; + us_memsink_s *h264_sink; +} us_options_s; -options_s *options_init(unsigned argc, char *argv[]); -void options_destroy(options_s *options); +us_options_s *us_options_init(unsigned argc, char *argv[]); +void us_options_destroy(us_options_s *options); -int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *stream, server_s *server); +int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us_stream_s *stream, us_server_s *server); diff --git a/src/ustreamer/stream.c b/src/ustreamer/stream.c index 0816f07..6308026 100644 --- a/src/ustreamer/stream.c +++ b/src/ustreamer/stream.c @@ -23,41 +23,41 @@ #include "stream.h" -static workers_pool_s *_stream_init_loop(stream_s *stream); -static workers_pool_s *_stream_init_one(stream_s *stream); -static void _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps); +static us_workers_pool_s *_stream_init_loop(us_stream_s *stream); +static us_workers_pool_s *_stream_init_one(us_stream_s *stream); +static void _stream_expose_frame(us_stream_s *stream, us_frame_s *frame, unsigned captured_fps); -#define RUN(_next) stream->run->_next +#define _RUN(x_next) stream->run->x_next -#define SINK_PUT(_sink, _frame) { \ - if (stream->_sink && memsink_server_check(stream->_sink, _frame)) {\ - memsink_server_put(stream->_sink, _frame); \ +#define _SINK_PUT(x_sink, x_frame) { \ + if (stream->x_sink && us_memsink_server_check(stream->x_sink, x_frame)) {\ + us_memsink_server_put(stream->x_sink, x_frame); \ } \ } -#define H264_PUT(_frame, _force_key) { \ - if (RUN(h264)) { \ - h264_stream_process(RUN(h264), _frame, _force_key); \ +#define _H264_PUT(x_frame, x_force_key) { \ + if (_RUN(h264)) { \ + us_h264_stream_process(_RUN(h264), x_frame, x_force_key); \ } \ } -stream_s *stream_init(device_s *dev, encoder_s *enc) { - stream_runtime_s *run; - A_CALLOC(run, 1); +us_stream_s *us_stream_init(us_device_s *dev, us_encoder_s *enc) { + us_stream_runtime_s *run; + US_CALLOC(run, 1); atomic_init(&run->stop, false); - video_s *video; - A_CALLOC(video, 1); - video->frame = frame_init(); + us_video_s *video; + US_CALLOC(video, 1); + video->frame = us_frame_init(); atomic_init(&video->updated, false); - A_MUTEX_INIT(&video->mutex); + US_MUTEX_INIT(&video->mutex); atomic_init(&video->has_clients, false); run->video = video; - stream_s *stream; - A_CALLOC(stream, 1); + us_stream_s *stream; + US_CALLOC(stream, 1); stream->dev = dev; stream->enc = enc; stream->last_as_blank = -1; @@ -68,42 +68,42 @@ stream_s *stream_init(device_s *dev, encoder_s *enc) { return stream; } -void stream_destroy(stream_s *stream) { - A_MUTEX_DESTROY(&RUN(video->mutex)); - frame_destroy(RUN(video->frame)); - free(RUN(video)); +void us_stream_destroy(us_stream_s *stream) { + US_MUTEX_DESTROY(&_RUN(video->mutex)); + us_frame_destroy(_RUN(video->frame)); + free(_RUN(video)); free(stream->run); free(stream); } -void stream_loop(stream_s *stream) { +void us_stream_loop(us_stream_s *stream) { assert(stream->blank); - LOG_INFO("Using V4L2 device: %s", stream->dev->path); - LOG_INFO("Using desired FPS: %u", stream->dev->desired_fps); + 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) { - RUN(h264) = h264_stream_init(stream->h264_sink, stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop); + _RUN(h264) = us_h264_stream_init(stream->h264_sink, stream->h264_m2m_path, stream->h264_bitrate, stream->h264_gop); } - for (workers_pool_s *pool; (pool = _stream_init_loop(stream)) != NULL;) { + for (us_workers_pool_s *pool; (pool = _stream_init_loop(stream)) != NULL;) { long double grab_after = 0; unsigned fluency_passed = 0; unsigned captured_fps = 0; unsigned captured_fps_accum = 0; long long captured_fps_second = 0; - LOG_INFO("Capturing ..."); + US_LOG_INFO("Capturing ..."); - while (!atomic_load(&RUN(stop))) { - SEP_DEBUG('-'); - LOG_DEBUG("Waiting for worker ..."); + while (!atomic_load(&_RUN(stop))) { + US_SEP_DEBUG('-'); + US_LOG_DEBUG("Waiting for worker ..."); - worker_s *ready_wr = workers_pool_wait(pool); - encoder_job_s *ready_job = (encoder_job_s *)(ready_wr->job); + us_worker_s *ready_wr = us_workers_pool_wait(pool); + us_encoder_job_s *ready_job = (us_encoder_job_s *)(ready_wr->job); if (ready_job->hw) { - if (device_release_buffer(stream->dev, ready_job->hw) < 0) { + if (us_device_release_buffer(stream->dev, ready_job->hw) < 0) { ready_wr->job_failed = true; } ready_job->hw = NULL; @@ -111,9 +111,9 @@ void stream_loop(stream_s *stream) { if (!ready_wr->job_failed) { if (ready_wr->job_timely) { _stream_expose_frame(stream, ready_job->dest, captured_fps); - LOG_PERF("##### Encoded frame exposed; worker=%s", ready_wr->name); + US_LOG_PERF("##### Encoded frame exposed; worker=%s", ready_wr->name); } else { - LOG_PERF("----- Encoded frame dropped; worker=%s", ready_wr->name); + US_LOG_PERF("----- Encoded frame dropped; worker=%s", ready_wr->name); } } else { break; @@ -123,51 +123,51 @@ void stream_loop(stream_s *stream) { bool h264_force_key = false; if (stream->slowdown) { unsigned slc = 0; - for (; slc < 10 && !atomic_load(&RUN(stop)) && !stream_has_clients(stream); ++slc) { + for (; slc < 10 && !atomic_load(&_RUN(stop)) && !us_stream_has_clients(stream); ++slc) { usleep(100000); ++slc; } h264_force_key = (slc == 10); } - if (atomic_load(&RUN(stop))) { + if (atomic_load(&_RUN(stop))) { break; } bool has_read; bool has_write; bool has_error; - int selected = device_select(stream->dev, &has_read, &has_write, &has_error); + int selected = us_device_select(stream->dev, &has_read, &has_write, &has_error); if (selected < 0) { if (errno != EINTR) { - LOG_PERROR("Mainloop select() error"); + US_LOG_PERROR("Mainloop select() error"); break; } } else if (selected == 0) { // Persistent timeout # ifdef WITH_GPIO - gpio_set_stream_online(false); + us_gpio_set_stream_online(false); # endif } else { if (has_read) { - LOG_DEBUG("Frame is ready"); + US_LOG_DEBUG("Frame is ready"); # ifdef WITH_GPIO - gpio_set_stream_online(true); + us_gpio_set_stream_online(true); # endif - const long double now = get_now_monotonic(); - const long long now_second = floor_ms(now); + const long double now = us_get_now_monotonic(); + const long long now_second = us_floor_ms(now); - hw_buffer_s *hw; - int buf_index = device_grab_buffer(stream->dev, &hw); + us_hw_buffer_s *hw; + int buf_index = us_device_grab_buffer(stream->dev, &hw); if (buf_index >= 0) { if (now < grab_after) { fluency_passed += 1; - LOG_VERBOSE("Passed %u frames for fluency: now=%.03Lf, grab_after=%.03Lf", + US_LOG_VERBOSE("Passed %u frames for fluency: now=%.03Lf, grab_after=%.03Lf", fluency_passed, now, grab_after); - if (device_release_buffer(stream->dev, hw) < 0) { + if (us_device_release_buffer(stream->dev, hw) < 0) { break; } } else { @@ -177,20 +177,20 @@ void stream_loop(stream_s *stream) { captured_fps = captured_fps_accum; captured_fps_accum = 0; captured_fps_second = now_second; - LOG_PERF_FPS("A new second has come; captured_fps=%u", captured_fps); + US_LOG_PERF_FPS("A new second has come; captured_fps=%u", captured_fps); } captured_fps_accum += 1; - const long double fluency_delay = workers_pool_get_fluency_delay(pool, ready_wr); + const long double fluency_delay = us_workers_pool_get_fluency_delay(pool, ready_wr); grab_after = now + fluency_delay; - LOG_VERBOSE("Fluency: delay=%.03Lf, grab_after=%.03Lf", fluency_delay, grab_after); + US_LOG_VERBOSE("Fluency: delay=%.03Lf, grab_after=%.03Lf", fluency_delay, grab_after); ready_job->hw = hw; - workers_pool_assign(pool, ready_wr); - LOG_DEBUG("Assigned new frame in buffer=%d to worker=%s", buf_index, ready_wr->name); + us_workers_pool_assign(pool, ready_wr); + US_LOG_DEBUG("Assigned new frame in buffer=%d to worker=%s", buf_index, ready_wr->name); - SINK_PUT(raw_sink, &hw->raw); - H264_PUT(&hw->raw, h264_force_key); + _SINK_PUT(raw_sink, &hw->raw); + _H264_PUT(&hw->raw, h264_force_key); } } else if (buf_index != -2) { // -2 for broken frame break; @@ -198,72 +198,72 @@ void stream_loop(stream_s *stream) { } if (has_write) { - LOG_ERROR("Got unexpected writing event, seems device was disconnected"); + US_LOG_ERROR("Got unexpected writing event, seems device was disconnected"); break; } if (has_error) { - LOG_INFO("Got V4L2 event"); - if (device_consume_event(stream->dev) < 0) { + US_LOG_INFO("Got V4L2 event"); + if (us_device_consume_event(stream->dev) < 0) { break; } } } } - workers_pool_destroy(pool); - device_switch_capturing(stream->dev, false); - device_close(stream->dev); + us_workers_pool_destroy(pool); + us_device_switch_capturing(stream->dev, false); + us_device_close(stream->dev); # ifdef WITH_GPIO - gpio_set_stream_online(false); + us_gpio_set_stream_online(false); # endif } - if (RUN(h264)) { - h264_stream_destroy(RUN(h264)); + if (_RUN(h264)) { + us_h264_stream_destroy(_RUN(h264)); } } -void stream_loop_break(stream_s *stream) { - atomic_store(&RUN(stop), true); +void us_stream_loop_break(us_stream_s *stream) { + atomic_store(&_RUN(stop), true); } -bool stream_has_clients(stream_s *stream) { +bool us_stream_has_clients(us_stream_s *stream) { return ( - atomic_load(&RUN(video->has_clients)) + atomic_load(&_RUN(video->has_clients)) // has_clients синков НЕ обновляются в реальном времени || (stream->sink != NULL && atomic_load(&stream->sink->has_clients)) - || (RUN(h264) != NULL && /*RUN(h264->sink) == NULL ||*/ atomic_load(&RUN(h264->sink->has_clients))) + || (_RUN(h264) != NULL && /*_RUN(h264->sink) == NULL ||*/ atomic_load(&_RUN(h264->sink->has_clients))) ); } -static workers_pool_s *_stream_init_loop(stream_s *stream) { +static us_workers_pool_s *_stream_init_loop(us_stream_s *stream) { - workers_pool_s *pool = NULL; + us_workers_pool_s *pool = NULL; int access_error = 0; - LOG_DEBUG("%s: stream->run->stop=%d", __FUNCTION__, atomic_load(&RUN(stop))); + US_LOG_DEBUG("%s: stream->run->stop=%d", __FUNCTION__, atomic_load(&_RUN(stop))); - while (!atomic_load(&RUN(stop))) { + while (!atomic_load(&_RUN(stop))) { _stream_expose_frame(stream, NULL, 0); if (access(stream->dev->path, R_OK|W_OK) < 0) { if (access_error != errno) { - SEP_INFO('='); - LOG_PERROR("Can't access device"); - LOG_INFO("Waiting for the device access ..."); + US_SEP_INFO('='); + US_LOG_PERROR("Can't access device"); + US_LOG_INFO("Waiting for the device access ..."); access_error = errno; } sleep(stream->error_delay); continue; } else { - SEP_INFO('='); + US_SEP_INFO('='); access_error = 0; } if ((pool = _stream_init_one(stream)) == NULL) { - LOG_INFO("Sleeping %u seconds before new stream init ...", stream->error_delay); + US_LOG_INFO("Sleeping %u seconds before new stream init ...", stream->error_delay); sleep(stream->error_delay); } else { break; @@ -272,90 +272,86 @@ static workers_pool_s *_stream_init_loop(stream_s *stream) { return pool; } -static workers_pool_s *_stream_init_one(stream_s *stream) { - if (device_open(stream->dev) < 0) { +static us_workers_pool_s *_stream_init_one(us_stream_s *stream) { + if (us_device_open(stream->dev) < 0) { goto error; } if ( - stream->enc->type == ENCODER_TYPE_M2M_VIDEO - || stream->enc->type == ENCODER_TYPE_M2M_IMAGE - || (RUN(h264) && !is_jpeg(stream->dev->run->format)) + stream->enc->type == US_ENCODER_TYPE_M2M_VIDEO + || stream->enc->type == US_ENCODER_TYPE_M2M_IMAGE + || (_RUN(h264) && !us_is_jpeg(stream->dev->run->format)) ) { - device_export_to_dma(stream->dev); + us_device_export_to_dma(stream->dev); } - if (device_switch_capturing(stream->dev, true) < 0) { + if (us_device_switch_capturing(stream->dev, true) < 0) { goto error; } - return encoder_workers_pool_init(stream->enc, stream->dev); + return us_encoder_workers_pool_init(stream->enc, stream->dev); error: - device_close(stream->dev); + us_device_close(stream->dev); return NULL; } -static void _stream_expose_frame(stream_s *stream, frame_s *frame, unsigned captured_fps) { -# define VID(_next) RUN(video->_next) +static void _stream_expose_frame(us_stream_s *stream, us_frame_s *frame, unsigned captured_fps) { +# define VID(x_next) _RUN(video->x_next) - frame_s *new = NULL; + us_frame_s *new = NULL; - A_MUTEX_LOCK(&VID(mutex)); + US_MUTEX_LOCK(&VID(mutex)); if (frame) { new = frame; - RUN(last_as_blank_ts) = 0; // Останавливаем таймер - LOG_DEBUG("Exposed ALIVE video frame"); + _RUN(last_as_blank_ts) = 0; // Останавливаем таймер + US_LOG_DEBUG("Exposed ALIVE video frame"); } else { if (VID(frame->used == 0)) { new = stream->blank; // Инициализация - RUN(last_as_blank_ts) = 0; + _RUN(last_as_blank_ts) = 0; } else if (VID(frame->online)) { // Если переходим из online в offline if (stream->last_as_blank < 0) { // Если last_as_blank выключен, просто покажем старую картинку new = stream->blank; - LOG_INFO("Changed video frame to BLANK"); + US_LOG_INFO("Changed video frame to BLANK"); } else if (stream->last_as_blank > 0) { // // Если нужен таймер - запустим - RUN(last_as_blank_ts) = get_now_monotonic() + stream->last_as_blank; - LOG_INFO("Freezed last ALIVE video frame for %d seconds", stream->last_as_blank); + _RUN(last_as_blank_ts) = us_get_now_monotonic() + stream->last_as_blank; + US_LOG_INFO("Freezed last ALIVE video frame for %d seconds", stream->last_as_blank); } else { // last_as_blank == 0 - показываем последний фрейм вечно - LOG_INFO("Freezed last ALIVE video frame forever"); + US_LOG_INFO("Freezed last ALIVE video frame forever"); } } else if (stream->last_as_blank < 0) { new = stream->blank; - // LOG_INFO("Changed video frame to BLANK"); + // US_LOG_INFO("Changed video frame to BLANK"); } if ( // Если уже оффлайн, включена фича last_as_blank с таймером и он запущен stream->last_as_blank > 0 - && RUN(last_as_blank_ts) != 0 - && RUN(last_as_blank_ts) < get_now_monotonic() + && _RUN(last_as_blank_ts) != 0 + && _RUN(last_as_blank_ts) < us_get_now_monotonic() ) { new = stream->blank; - RUN(last_as_blank_ts) = 0; // // Останавливаем таймер - LOG_INFO("Changed last ALIVE video frame to BLANK"); + _RUN(last_as_blank_ts) = 0; // // Останавливаем таймер + US_LOG_INFO("Changed last ALIVE video frame to BLANK"); } } if (new) { - frame_copy(new, VID(frame)); + us_frame_copy(new, VID(frame)); } VID(frame->online) = (bool)frame; VID(captured_fps) = captured_fps; atomic_store(&VID(updated), true); - A_MUTEX_UNLOCK(&VID(mutex)); + US_MUTEX_UNLOCK(&VID(mutex)); new = (frame ? frame : stream->blank); - SINK_PUT(sink, new); + _SINK_PUT(sink, new); if (frame == NULL) { - SINK_PUT(raw_sink, stream->blank); - H264_PUT(stream->blank, false); + _SINK_PUT(raw_sink, stream->blank); + _H264_PUT(stream->blank, false); } # undef VID } - -#undef H264_PUT -#undef SINK_PUT -#undef RUN diff --git a/src/ustreamer/stream.h b/src/ustreamer/stream.h index d0f4aa1..05e65a3 100644 --- a/src/ustreamer/stream.h +++ b/src/ustreamer/stream.h @@ -49,48 +49,48 @@ typedef struct { - frame_s *frame; + us_frame_s *frame; unsigned captured_fps; atomic_bool updated; pthread_mutex_t mutex; atomic_bool has_clients; // For slowdown -} video_s; +} us_video_s; typedef struct { - video_s *video; - long double last_as_blank_ts; + us_video_s *video; + long double last_as_blank_ts; - h264_stream_s *h264; + us_h264_stream_s *h264; - atomic_bool stop; -} stream_runtime_s; + atomic_bool stop; +} us_stream_runtime_s; typedef struct { - device_s *dev; - encoder_s *enc; + us_device_s *dev; + us_encoder_s *enc; - frame_s *blank; - int last_as_blank; - bool slowdown; - unsigned error_delay; + us_frame_s *blank; + int last_as_blank; + bool slowdown; + unsigned error_delay; - memsink_s *sink; - memsink_s *raw_sink; + us_memsink_s *sink; + us_memsink_s *raw_sink; - memsink_s *h264_sink; - unsigned h264_bitrate; - unsigned h264_gop; - char *h264_m2m_path; + us_memsink_s *h264_sink; + unsigned h264_bitrate; + unsigned h264_gop; + char *h264_m2m_path; - stream_runtime_s *run; -} stream_s; + us_stream_runtime_s *run; +} us_stream_s; -stream_s *stream_init(device_s *dev, encoder_s *enc); -void stream_destroy(stream_s *stream); +us_stream_s *us_stream_init(us_device_s *dev, us_encoder_s *enc); +void us_stream_destroy(us_stream_s *stream); -void stream_loop(stream_s *stream); -void stream_loop_break(stream_s *stream); +void us_stream_loop(us_stream_s *stream); +void us_stream_loop_break(us_stream_s *stream); -bool stream_has_clients(stream_s *stream); +bool us_stream_has_clients(us_stream_s *stream); diff --git a/src/ustreamer/workers.c b/src/ustreamer/workers.c index dfcf919..a3b8b09 100644 --- a/src/ustreamer/workers.c +++ b/src/ustreamer/workers.c @@ -26,16 +26,16 @@ static void *_worker_thread(void *v_worker); -workers_pool_s *workers_pool_init( +us_workers_pool_s *us_workers_pool_init( const char *name, const char *wr_prefix, unsigned n_workers, long double desired_interval, - workers_pool_job_init_f job_init, void *job_init_arg, - workers_pool_job_destroy_f job_destroy, - workers_pool_run_job_f run_job) { + us_workers_pool_job_init_f job_init, void *job_init_arg, + us_workers_pool_job_destroy_f job_destroy, + us_workers_pool_run_job_f run_job) { - LOG_INFO("Creating pool %s with %u workers ...", name, n_workers); + US_LOG_INFO("Creating pool %s with %u workers ...", name, n_workers); - workers_pool_s *pool; - A_CALLOC(pool, 1); + us_workers_pool_s *pool; + US_CALLOC(pool, 1); pool->name = name; pool->desired_interval = desired_interval; pool->job_destroy = job_destroy; @@ -44,25 +44,25 @@ workers_pool_s *workers_pool_init( atomic_init(&pool->stop, false); pool->n_workers = n_workers; - A_CALLOC(pool->workers, pool->n_workers); + US_CALLOC(pool->workers, pool->n_workers); - A_MUTEX_INIT(&pool->free_workers_mutex); - A_COND_INIT(&pool->free_workers_cond); + US_MUTEX_INIT(&pool->free_workers_mutex); + US_COND_INIT(&pool->free_workers_cond); for (unsigned number = 0; number < pool->n_workers; ++number) { -# define WR(_next) pool->workers[number]._next +# define WR(x_next) pool->workers[number].x_next WR(number) = number; - A_ASPRINTF(WR(name), "%s-%u", wr_prefix, number); + US_ASPRINTF(WR(name), "%s-%u", wr_prefix, number); - A_MUTEX_INIT(&WR(has_job_mutex)); + US_MUTEX_INIT(&WR(has_job_mutex)); atomic_init(&WR(has_job), false); - A_COND_INIT(&WR(has_job_cond)); + US_COND_INIT(&WR(has_job_cond)); WR(pool) = pool; WR(job) = job_init(job_init_arg); - A_THREAD_CREATE(&WR(tid), _worker_thread, (void *)&(pool->workers[number])); + US_THREAD_CREATE(&WR(tid), _worker_thread, (void *)&(pool->workers[number])); pool->free_workers += 1; # undef WR @@ -70,21 +70,21 @@ workers_pool_s *workers_pool_init( return pool; } -void workers_pool_destroy(workers_pool_s *pool) { - LOG_INFO("Destroying workers pool %s ...", pool->name); +void us_workers_pool_destroy(us_workers_pool_s *pool) { + US_LOG_INFO("Destroying workers pool %s ...", pool->name); atomic_store(&pool->stop, true); for (unsigned number = 0; number < pool->n_workers; ++number) { -# define WR(_next) pool->workers[number]._next +# define WR(x_next) pool->workers[number].x_next - A_MUTEX_LOCK(&WR(has_job_mutex)); + US_MUTEX_LOCK(&WR(has_job_mutex)); atomic_store(&WR(has_job), true); // Final job: die - A_MUTEX_UNLOCK(&WR(has_job_mutex)); - A_COND_SIGNAL(&WR(has_job_cond)); + US_MUTEX_UNLOCK(&WR(has_job_mutex)); + US_COND_SIGNAL(&WR(has_job_cond)); - A_THREAD_JOIN(WR(tid)); - A_MUTEX_DESTROY(&WR(has_job_mutex)); - A_COND_DESTROY(&WR(has_job_cond)); + US_THREAD_JOIN(WR(tid)); + US_MUTEX_DESTROY(&WR(has_job_mutex)); + US_COND_DESTROY(&WR(has_job_cond)); free(WR(name)); @@ -93,19 +93,19 @@ void workers_pool_destroy(workers_pool_s *pool) { # undef WR } - A_MUTEX_DESTROY(&pool->free_workers_mutex); - A_COND_DESTROY(&pool->free_workers_cond); + US_MUTEX_DESTROY(&pool->free_workers_mutex); + US_COND_DESTROY(&pool->free_workers_cond); free(pool->workers); free(pool); } -worker_s *workers_pool_wait(workers_pool_s *pool) { - worker_s *ready_wr = NULL; +us_worker_s *us_workers_pool_wait(us_workers_pool_s *pool) { + us_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); - A_MUTEX_UNLOCK(&pool->free_workers_mutex); + US_MUTEX_LOCK(&pool->free_workers_mutex); + US_COND_WAIT_TRUE(pool->free_workers, &pool->free_workers_cond, &pool->free_workers_mutex); + US_MUTEX_UNLOCK(&pool->free_workers_mutex); if (pool->oldest_wr && !atomic_load(&pool->oldest_wr->has_job)) { ready_wr = pool->oldest_wr; @@ -129,7 +129,7 @@ worker_s *workers_pool_wait(workers_pool_s *pool) { return ready_wr; } -void workers_pool_assign(workers_pool_s *pool, worker_s *ready_wr/*, void *job*/) { +void us_workers_pool_assign(us_workers_pool_s *pool, us_worker_s *ready_wr/*, void *job*/) { if (pool->oldest_wr == NULL) { pool->oldest_wr = ready_wr; pool->latest_wr = pool->oldest_wr; @@ -146,21 +146,21 @@ void workers_pool_assign(workers_pool_s *pool, worker_s *ready_wr/*, void *job*/ } pool->latest_wr->next_wr = NULL; - A_MUTEX_LOCK(&ready_wr->has_job_mutex); + US_MUTEX_LOCK(&ready_wr->has_job_mutex); //ready_wr->job = job; atomic_store(&ready_wr->has_job, true); - A_MUTEX_UNLOCK(&ready_wr->has_job_mutex); - A_COND_SIGNAL(&ready_wr->has_job_cond); + US_MUTEX_UNLOCK(&ready_wr->has_job_mutex); + US_COND_SIGNAL(&ready_wr->has_job_cond); - A_MUTEX_LOCK(&pool->free_workers_mutex); + US_MUTEX_LOCK(&pool->free_workers_mutex); pool->free_workers -= 1; - A_MUTEX_UNLOCK(&pool->free_workers_mutex); + US_MUTEX_UNLOCK(&pool->free_workers_mutex); } -long double workers_pool_get_fluency_delay(workers_pool_s *pool, worker_s *ready_wr) { +long double us_workers_pool_get_fluency_delay(us_workers_pool_s *pool, us_worker_s *ready_wr) { const long double approx_job_time = pool->approx_job_time * 0.9 + ready_wr->last_job_time * 0.1; - LOG_VERBOSE("Correcting pool's %s approx_job_time: %.3Lf -> %.3Lf (last_job_time=%.3Lf)", + US_LOG_VERBOSE("Correcting pool's %s approx_job_time: %.3Lf -> %.3Lf (last_job_time=%.3Lf)", pool->name, pool->approx_job_time, approx_job_time, ready_wr->last_job_time); pool->approx_job_time = approx_job_time; @@ -176,35 +176,35 @@ long double workers_pool_get_fluency_delay(workers_pool_s *pool, worker_s *ready } static void *_worker_thread(void *v_worker) { - worker_s *wr = (worker_s *)v_worker; + us_worker_s *wr = (us_worker_s *)v_worker; - A_THREAD_RENAME("%s", wr->name); - LOG_DEBUG("Hello! I am a worker %s ^_^", wr->name); + US_THREAD_RENAME("%s", wr->name); + US_LOG_DEBUG("Hello! I am a worker %s ^_^", wr->name); while (!atomic_load(&wr->pool->stop)) { - LOG_DEBUG("Worker %s waiting for a new job ...", wr->name); + US_LOG_DEBUG("Worker %s waiting for a new job ...", wr->name); - A_MUTEX_LOCK(&wr->has_job_mutex); - A_COND_WAIT_TRUE(atomic_load(&wr->has_job), &wr->has_job_cond, &wr->has_job_mutex); - A_MUTEX_UNLOCK(&wr->has_job_mutex); + US_MUTEX_LOCK(&wr->has_job_mutex); + US_COND_WAIT_TRUE(atomic_load(&wr->has_job), &wr->has_job_cond, &wr->has_job_mutex); + US_MUTEX_UNLOCK(&wr->has_job_mutex); if (!atomic_load(&wr->pool->stop)) { - long double job_start_ts = get_now_monotonic(); + 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; - wr->last_job_time = get_now_monotonic() - wr->job_start_ts; + wr->last_job_time = us_get_now_monotonic() - wr->job_start_ts; } //wr->job = NULL; atomic_store(&wr->has_job, false); } - A_MUTEX_LOCK(&wr->pool->free_workers_mutex); + US_MUTEX_LOCK(&wr->pool->free_workers_mutex); wr->pool->free_workers += 1; - A_MUTEX_UNLOCK(&wr->pool->free_workers_mutex); - A_COND_SIGNAL(&wr->pool->free_workers_cond); + US_MUTEX_UNLOCK(&wr->pool->free_workers_mutex); + US_COND_SIGNAL(&wr->pool->free_workers_cond); } - LOG_DEBUG("Bye-bye (worker %s)", wr->name); + US_LOG_DEBUG("Bye-bye (worker %s)", wr->name); return NULL; } diff --git a/src/ustreamer/workers.h b/src/ustreamer/workers.h index 91ab8b1..c3fa69e 100644 --- a/src/ustreamer/workers.h +++ b/src/ustreamer/workers.h @@ -34,7 +34,7 @@ #include "../libs/logging.h" -typedef struct worker_sx { +typedef struct us_worker_sx { pthread_t tid; unsigned number; char *name; @@ -49,27 +49,27 @@ typedef struct worker_sx { long double job_start_ts; pthread_cond_t has_job_cond; - struct worker_sx *prev_wr; - struct worker_sx *next_wr; + struct us_worker_sx *prev_wr; + struct us_worker_sx *next_wr; - struct workers_pool_sx *pool; -} worker_s; + struct us_workers_pool_sx *pool; +} us_worker_s; -typedef void *(*workers_pool_job_init_f)(void *arg); -typedef void (*workers_pool_job_destroy_f)(void *job); -typedef bool (*workers_pool_run_job_f)(worker_s *wr); +typedef void *(*us_workers_pool_job_init_f)(void *arg); +typedef void (*us_workers_pool_job_destroy_f)(void *job); +typedef bool (*us_workers_pool_run_job_f)(us_worker_s *wr); -typedef struct workers_pool_sx { +typedef struct us_workers_pool_sx { const char *name; long double desired_interval; - workers_pool_job_destroy_f job_destroy; - workers_pool_run_job_f run_job; + us_workers_pool_job_destroy_f job_destroy; + us_workers_pool_run_job_f run_job; unsigned n_workers; - worker_s *workers; - worker_s *oldest_wr; - worker_s *latest_wr; + us_worker_s *workers; + us_worker_s *oldest_wr; + us_worker_s *latest_wr; long double approx_job_time; @@ -78,18 +78,18 @@ typedef struct workers_pool_sx { pthread_cond_t free_workers_cond; atomic_bool stop; -} workers_pool_s; +} us_workers_pool_s; -workers_pool_s *workers_pool_init( +us_workers_pool_s *us_workers_pool_init( const char *name, const char *wr_prefix, unsigned n_workers, long double desired_interval, - workers_pool_job_init_f job_init, void *job_init_arg, - workers_pool_job_destroy_f job_destroy, - workers_pool_run_job_f run_job); + us_workers_pool_job_init_f job_init, void *job_init_arg, + us_workers_pool_job_destroy_f job_destroy, + us_workers_pool_run_job_f run_job); -void workers_pool_destroy(workers_pool_s *pool); +void us_workers_pool_destroy(us_workers_pool_s *pool); -worker_s *workers_pool_wait(workers_pool_s *pool); -void workers_pool_assign(workers_pool_s *pool, worker_s *ready_wr/*, void *job*/); +us_worker_s *us_workers_pool_wait(us_workers_pool_s *pool); +void us_workers_pool_assign(us_workers_pool_s *pool, us_worker_s *ready_wr/*, void *job*/); -long double workers_pool_get_fluency_delay(workers_pool_s *pool, worker_s *ready_wr); +long double us_workers_pool_get_fluency_delay(us_workers_pool_s *pool, us_worker_s *ready_wr); diff --git a/tools/make-html-h.py b/tools/make-html-h.py index 2220744..ddcd9a6 100755 --- a/tools/make-html-h.py +++ b/tools/make-html-h.py @@ -41,7 +41,7 @@ def main() -> None: html = html.strip() html = html.replace("\"", "\\\"") - html = html.replace("%VERSION%", "\" VERSION \"") + html = html.replace("%VERSION%", "\" US_VERSION \"") html = textwrap.indent(html, "\t", (lambda line: True)) html = "\n".join( (f"{line} \\" if line.strip() else f"{line}\\") @@ -49,7 +49,7 @@ def main() -> None: ) text = f"{common.C_PREPEND}\n#include \"{h_path}\"\n\n\n" - text += f"const char *const HTML_{name}_PAGE = \" \\\n{html}\n\";\n" + text += f"const char *const US_HTML_{name}_PAGE = \" \\\n{html}\n\";\n" with open(c_path, "w") as c_file: c_file.write(text) diff --git a/tools/make-jpeg-h.py b/tools/make-jpeg-h.py index b66c2e9..64691ef 100755 --- a/tools/make-jpeg-h.py +++ b/tools/make-jpeg-h.py @@ -82,10 +82,10 @@ def main() -> None: text = f"{common.C_PREPEND}\n" text += f"#include \"{h_path}\"\n\n\n" - text += f"const unsigned {name}_JPEG_WIDTH = {width};\n" - text += f"const unsigned {name}_JPEG_HEIGHT = {height};\n\n" - text += f"const size_t {name}_JPEG_DATA_SIZE = {len(jpeg_data)};\n" - text += f"const uint8_t {name}_JPEG_DATA[] = {jpeg_data_text};\n" + text += f"const unsigned US_{name}_JPEG_WIDTH = {width};\n" + text += f"const unsigned US_{name}_JPEG_HEIGHT = {height};\n\n" + text += f"const size_t US_{name}_JPEG_DATA_SIZE = {len(jpeg_data)};\n" + text += f"const uint8_t US_{name}_JPEG_DATA[] = {jpeg_data_text};\n" with open(c_path, "w") as c_file: c_file.write(text)